内部模块现在称做“命名空间”。 外部模块现在则简称为“模块”
模块
export: 导出声明的关键字
- 导入一个模块的多个模块: export * from ‘module’
import:
- 导入一个模块的某个导出内容:
1
2import { xx } from 'module'
let a = new xx - 导入内容重命名:
1
import { xx as a } from 'module'
- 将整个模块导入到一个变量,并通过它来访问模块的导出部分
1
2import * as validator from "./ZipCodeValidator"
let myValidator = new validator.ZipCodeValidator() - 具有副作用的导入模块
- 设置全局状态供其它模块使用(该模块可能没有任何导出或没人在意他的导出):
1
import "./my-module.js";
默认导出: export default(也可以导出一个值)
export = 语法: 用来支持传统的CommonJS和AMD的工作流模块
- 定义一个模块的导出对象,这里的对象一词指的是类,接口,命名空间,函数或枚举。
- 若要导入使用该语法的模块,则必须使用Ts的特定语法
1
import module = require("module")
生成模块代码
1 | import {xx} from 'module' // es6 |
- 编译 :
- 对于node.js:
1
tsc --module commonjs xxx.ts
- 对于require.js:
1
tsc --module amd xxx.ts
- 对于node.js:
可选模块加载和其它高级加载场景
- 模块核心是import id = require(“…”)语句可以让我们访问模块导出的类型
- 为了确保类型安全性,使用typeof关键字,当在表示类型的地方使用时,会得出一个类型值,这里就表示模块的类型
使用其他的js库: 通常在.d.ts文件里定义的
在Node.js里大部分工作是通过加载一个或多个模块实现的。
1
2
3
4
5
6declare module "url" {
export interface Url {
hostname?: string
}
}
import name = requir("module")加载模块的方法:
- 方法一: 使用///语句和es6规范引入
1
2
3/// <reference> path="node.d.ts" />
import * as URL from "url"
let myUrl = URL.parse("http://www.typescriptlang.org"); - 方法二: 使用///语句和commonJS规范引入
1
2/// <reference> path="node.d.ts" />
import url = require("url");
- 方法一: 使用///语句和es6规范引入
外部模块简写:
1
2
3declare module "name" // 简写模块里所有导出的类型将是any
import x, {y} from "hot-new-module";
x(y);模块声明通配符:
- 向SystemJS和AMD支持加载非js内容,就可以使用前缀*!或后缀!*加载
1
2
3
4
5
6
7
8
9
10declare module "*!test" {
const content : string
export default content
}
declare module "json!*"{
const value : any
export default value
}
import file from "./xxx!test"
import data from "json!http://example.com/data.json"
- 向SystemJS和AMD支持加载非js内容,就可以使用前缀*!或后缀!*加载
UMD模块:
有些模块被设计成兼容多个模块加载器,或不使用模块加载器(全局变量)
这些库可以通过导入的形式或全局变量的形式访问
1 | export function isPrime(x:number) : boolean |
注意:
- 尽可能在顶层导出,导入只明确导入的名字
1
import { a, b } from "./路径"
- 如果仅导出『单个class或单个function』
1
export default
- 使用命名空间导入:
1
import * as name from "./路径"
- 模块里不要使用命名空间
命名空间namespace:
- 一个模块的多个模块用namespace name{}来包裹,其中的每个模块都使用了export关键字
- 多文件中的命名空间: 就是同一个命名空间,但模块被拆分在不同的文件中,在不同文件中的被拆分模块外层都保留它原有的命名空间
- 编译:
- 把所有的输入文件编译为一个输出文件
1
tsc --outFile xxx.js xx.ts
- 编译每个文件后通过页面的script标签按顺序引入
- 把所有的输入文件编译为一个输出文件
- 别名: 简化命名空间操作的方法是使用import q = x.y.z
1
2
3
4
5
6
7
8
9namespace Shapes {
export namespace Polygons {
export class Triangle { }
export class Square { }
}
}
import polygons = Shapes.Polygons;
let sq = new polygons.Square();
外部命名空间: 在.d.ts中写
- 如程序库D3在全局对象d3中定义它的功能,因为这个库通过一个script标签加载,它的声明文件使用内部模块来定义它的类型。Ts编译器使用外部命名空间声明才能识别
1
2
3
4
5
6
7
8
9
10
11declare namespace D3 {
export interface Event {
x: number;
y: number;
}
export interface Base extends Selectors {
event: Event;
}
}
declare var d3: D3.Base;
命名空间和模块: 大型使用模块,小型项目使用命名空间
- 陷阱:
- 应该使用import引用模块文件,而非
1
/// <reference>
- 应该使用import引用模块文件,而非
- 不应该对模块使用命名空间
- 模块的取舍: 指定的模块系统不同,可能无法连接多个模块源文件