命名空间

命名空间能有效避免全局污染。在ES6引入模块之后,命名空间就较少被提及了。如果使用了全局的类库,命名空间仍是一个好的解决方案。

namespace Shape{
const pi = Math.PI;
// 使用export关键字导出,可以在全局空间内可见
export function circle(r: number) {
return pi * r ** 2
}
square(5)
}
Shape.circle(10); // 可以在全局空间访问导出的
import circle = Shape.circle; // 为命名空间内的变量起个别名,要清楚此处import与模块化的import含义不一样
circle(20);

随着程序的扩张,命名空间也会很大,需要对其进行拆分,在不同的文件中使用同名命名空间,他们之间共享命名空间。

// space1.ts
/// <reference path="space2.ts" /> // 三斜线引用标签告诉编译器,两个文件中的命名空间内部存在着依赖关系
namespace Shape{
export function square(x: number) {
return x*x;
}
circle(10); // 只有circle被export后,这里才能访问
} // space2.ts
/// <reference path="space1.ts" />
namespace Shape{
const pi = Math.PI;
// 使用export关键字导出,可以在全局空间内可见
export function circle(r: number) {
return pi * r ** 2
}
square(5);
}

命名空间最好不要和模块一起混用

模块化系统

TypeScript对ES6和CommonJS两种模块系统都有很好的支持,我们基本可以沿用以前的写法。但两者不要混用,如果出现混用,就要使用TS准备的兼容性写法。

先来看看ES6和CommonJS各自的写法

// ES6导入
import { a, b } from './Modular System/es6/a';
import { a as f } from './Modular System/es6/a';
import * as All from './Modular System/es6/a';
import abc from './Modular System/es6/b';
import Obj from './Modular System/es6/a'
// ES6导出
export defalut Obj;
export {a,b,c};
export {d as D};
export {D as C} from './a'; // 将a.ts中的D重新命名并导出,这种用法只能对a.ts中的非默认导出有效 // CommonJS导入
let c1 = require('./Modular System/node/a.ts');
let c2 = require('./Modular System/node/b');
// CommonJS导出
module.exports = a; // 将a变量导出
exports.c = 3;
exports.d = 4;
相当于
module.exports = {c:3, d:4}
如果两种方式并存,module.exports将会覆盖exports.c这种方式的导出

两种模块在导入导出时互不兼容:

  • 导出:ES6允许同时存在export default和export多个变量,而CommonJS只允许有一种形式的导出,其中一种会把另外一种覆盖掉。
  • 导入:ES6可以按需导入也可以全部导入,而CommonJS只能全部导入。

如果在ES6模块中抛出数据,在非ES6模块中导入,就会出现问题。因此尽量不要混用不同的模块化系统。如果迫不得已,可以使用TS提供的兼容性语法:

// 导出
export = a;
// 导入
import c4 = require('../es6/c');
/*
1.如果使用以上方法导出,此文件不允许有其它形式的导出
2.以上形式的导出的数据,不仅可以用以上语法导入,还可以用es6的方式导入。前提是tsconfig.json中的"esModuleInterop":true配置项要开启。
*/

声明合并

编译器会把程序的多个地方具有相同名称的声明合并成一个,这样可以将程序散落在各处的重名声明合并在一起。

例如:

interface StateMerge {
x: number,
y: string,
}
interface StateMerge {
y: string;
foo(bar: string[]): string[],
}
// 此时会将两个声明的同名接口成员合并
let stateMerge: StateMerge = {
x: 1,
y: "15",
foo(bar: any) {
return bar
}
};

如果合并的两个结构内成员重名怎么办?

  • 对于非函数成员,必须类型一致,否则报错。
  • 对于函数成员,会发生重载,重载的顺序按照以下规则。
interface StateMerge {
x: number,
y: string,
foo(bar: number): number; // 4
foo(bar: string): string; // 5
foo(bar: "b"): number; // 2
}
interface StateMerge {
y: string;
foo(bar: string[]): string[], // 3
foo(bar: "a"): number, // 1
}

接口内部按照先后顺序。接口之间,声明在后的接口函数成员排序更靠前。

如果出现自变量,排名最靠前。后面的接口中的排在第一位,前面的接口排在第二位。上述排序如注释所示。

函数和命名空间的合并

function Lib() {
}
namespace Lib{
export let version = '1.0'
}
console.log(Lib.version); // 相当于为函数Lib添加了属性

类和命名空间的合并

class C{
}
namespace C{
export let state = 1
}
console.log(C.state); // 相当于为类C添加了state属性

此外,还可以为枚举增加属性。

注意:在命名空间与类、函数进行生命合并的时候,一定要将命名空间放在类、函数之后。否则报错。

TypeScript模块系统、命名空间、声明合并的更多相关文章

  1. TypeScript 素描 - 模块解析、声明合并

    模块解析 模块解析有两种方式 相对方式  也就是以/或 ./或-/开头的,比如import jq  from "/jq" 非相对方式  比如 import model  from ...

  2. TypeScript 模块系统

    https://www.cnblogs.com/niklai/p/5808789.html

  3. 转载:《TypeScript 中文入门教程》 11、声明合并

    版权 文章转载自:https://github.com/zhongsp 建议您直接跳转到上面的网址查看最新版本. 介绍 TypeScript有一些独特的概念,有的是因为我们需要描述JavaScript ...

  4. TypeScript Declaration Merging(声明合并)

    TypeScript中有一些独特的概念,来自需要描述JavaScript对象类型发生了哪些变化.举个例子,最为独特的概念就是"声明合并".理解了这个概念将会对你在当前JavaScr ...

  5. TypeScript 素描 - 模块、命名空间

    /* 其实前面一些都是废话,因为都和C#类似.从模块开始就需要深入的去理解了 文档反复声明了 内部模块现在称做 命令空间 外部模块称为 模块 模块在其自身的作用域里执行,而不是在全局作用域里,也就是说 ...

  6. Typescript 实战 --- (9)ES6与CommonJS的模块系统

    1.ES6模块系统 1-1.export 导出 (1).单独导出 // a.ts export let a = 1; (2).批量导出 // a.ts let b = 2; let c = 3; ex ...

  7. TypeScript完全解读(26课时)_15.模块和命名空间

    新建文件夹ts-modules 并新建index.ts 在根index.ts内引入 新建a.ts文件 ts在1.5之前有两个概念一个是内部模块,一个是外部模块,因为在1.5之前es6的标准还没有提出 ...

  8. TypeScript完全解读(26课时)_16.声明合并

    ts编辑器会将名字相同的多个声明合并为一个声明,合并后的声明,同时拥有多个声明的特性 example文件夹下新建merging.ts文件 定义相同名字的接口, 定义变量类型是上面的接口.,光写一个na ...

  9. 全面解析ECMAScript 6模块系统

    快速使用Romanysoft LAB的技术实现 HTML 开发Mac OS App,并销售到苹果应用商店中.   <HTML开发Mac OS App 视频教程> 土豆网同步更新:http: ...

随机推荐

  1. Oracle创建设置查询权限用户

    用户创建的可以参考博客: https://blog.csdn.net/u014427391/article/details/84889023 Oracle授权表权限给用户: 语法:grant [权限名 ...

  2. 每个程序员都可以「懂」一点 Linux

    提到 Linux,作为程序员来说一定都不陌生.但如果说到「懂」Linux,可能就没有那么多人有把握了.到底用 Linux 离懂 Linux 有多远?如果决定学习 Linux,应该怎么开始?要学到什么程 ...

  3. 《机器学习技法》---线性SVM

    (本文内容和图片来自林轩田老师<机器学习技法>) 1. 线性SVM的推导 1.1 形象理解为什么要使用间隔最大化 容忍更多的测量误差,更加的robust.间隔越大,噪声容忍度越大: 1.2 ...

  4. Java基础及JavaWEB以及SSM框架学习笔记Xmind版

    Java基础及JavaWEB以及SSM框架学习笔记Xmind版 转行做程序员也1年多了,最近开始整理以前学习过程中记录的笔记,以及一些容易犯错的内容.现在分享给网友们.笔记共三部分. JavaSE 目 ...

  5. 谷歌移动UI框架Flutter教程之Widget

    引言 在之间我已经介绍了关于Flutter的下载安装以及配置,还有开发工具Android Studio的配置,还不知道的同学可以看看我这篇博客--谷歌移动UI框架Flutter入门.这里为什么非要用A ...

  6. Leetcode 5. Longest Palindromic Substring(最长回文子串, Manacher算法)

    Leetcode 5. Longest Palindromic Substring(最长回文子串, Manacher算法) Given a string s, find the longest pal ...

  7. unity编辑器扩展_05(删除游戏对象并具有撤回功能)

    代码: [MenuItem("Tools/Delete",false,1)]    static void Delete()    {        GameObject[] go ...

  8. 基于springboot的websocket聊天室

    WebSocket入门 1.概述 1.1 Http #http简介 HTTP是一个应用层协议,无状态的,端口号为80.主要的版本有1.0/1.1/2.0. #http1.0/1.1/2.0 1.HTT ...

  9. 数据的查找和提取[2]——xpath解析库的使用

    xpath解析库的使用 在上一节,我们介绍了正则表达式的使用,但是当我们提取数据的限制条件增多的时候,正则表达式会变的十分的复杂,出一丁点错就提取不出来东西了.但python已经为我们提供了许多用于解 ...

  10. 前端H5与安卓和ios之间通信

    在一些app场景中,经常看到app里面嵌套H5页面, 安卓和ios提供一个空壳子,方法两者互相调用.上一周就是写H5页面让安卓和ios调用使用,中间传参,接受参数.通过 window.wx 对象调用一 ...