09Typescript中的命名空间

介绍

在代码量较大的情况下,为了避免各种变量命名相冲突,可将相似功能的函数、类、接口等放置到命名空间内。

同 Java 的包、.Net 的命名空间一样,TypeScript 的命名空间可以将代码包裹起来,只对外暴露需要在外部访问的对象。命名空间内的对象通过 export 关键字对外暴露。

命名空间和模块的区别:
命名空间:内部模块,主要用于组织代码,避免命名冲突。
模 块:ts 的外部模块的简称,侧重代码的复用,一个模块里可能会有多个命名空间。

如何使用

引用一个前面使用过的列子 Animal ,把他放在命名空间 A 中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
namespace A {
interface Animal {
name: string;
eat(): void;
}
let num: number = 123;
export class Dog implements Animal {
name: string;
constructor(theName: string) {
this.name = theName;
}
eat() {
console.log(`${this.name} 在吃狗粮。`);
}
}
}

var d = new A.Dog("小狼");
d.eat(); //小狼 在吃狗粮。

从上面我们可以看出,我们把所有与 Animal 相关的类型都放到一个叫做 A 的命名空间里,因为我们想让这些接口和类在命名空间之外也是可访问的,所以需要使用 export。 相反的,变量 num 没有导出,因此在命名空间外是不能访问的。 在文件末尾的测试代码里,由于是在命名空间之外访问,因此需要限定类型的名称,比如 A.Dog.

多个命名空间

现在,我们在增加一个 B 命名空间,同时用模块的方式导出:

animal.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
export namespace A {
interface Animal {
name: string;
eat(): void;
}
export class Dog implements Animal {
name: string;
constructor(theName: string) {
this.name = theName;
}
eat() {
console.log(`${this.name} 在吃狗粮。`);
}
}
}

export namespace B {
interface Animal {
name: string;
eat(): void;
}
export class Dog implements Animal {
name: string;
constructor(theName: string) {
this.name = theName;
}
eat() {
console.log(`${this.name} 在吃狗粮。`);
}
}
}

index.ts

1
2
3
4
5
6
import { A, B } from "./animal";
var d = new A.Dog("小狼");
d.eat(); //小狼 在吃狗粮。

var d1 = new B.Dog("小狼2");
d1.eat(); //小狼2 在吃狗粮。