命名空间
命名空间就是之前的内部模块,任何以module关键字声明的内部模块,现在都使用namespace关键字进行替换。
命名空间指在代码量较大的情况下,为了避免各种变量冲突,将功能相近的函数、类、接口等放置到命名空间;命名空间和模块化还是有些区别的,命名空间是内部模块主要是组织规划代码避免冲突,模块通常指的是外部模块,解决代码复用的问题,在一个模块中可能会存有多个命名空间
开始
首先看一下在不使用命名空间是代码可能会是这样
interface Animal{
name:string;
say():void;
}
class Cat implements Animal{
name:string;
constructor(name:string){
this.name = name;
}
say(){console.log('我是兔子')}
}
class Rat implements Animal{
name:string;
constructor(name:string){
this.name = name;
}
say(){console.log('我是鹦鹉')}
}
如果只是简单的这样就实现了项目需求则没有问题,如果需求增多,多名开发协同进行,可能会引起变量冲突,比方A接到需求做rat起了名字叫‘老鼠’,B街道需求要做‘mouse’起名也叫‘老鼠’
定义命名空间
将上面的例子使用命名空间进行优化
namespace A{
interface Animal{...}
class Cat implements Animal{...}
class Rat implements Animal{...}
}
namespace B{
interface Animal{...}
class Cat implements Animal{...}
class Rat implements Animal{...}
}
这样开发B在自己的命名空间B中同样定义了同名方法则不会引起异常;
外部调用
现在我们有了命名空间,接口私有就好,需要将其中创建的类暴露出来,叫由外部空间使用
namespace A{
interface Animal{
name:string;
say():void;
}
export class Cat implements Animal{
name:string;
constructor(name:string){
this.name = name;
}
say(){console.log('我是兔子')}
}
}
let dahuang = new A.Cat('dahuang');
dahuang.say();//我是兔子
文件拆分
当应用变得越来越大时,我们需要将代码分离到不同的文件中以便于维护。这里可以使用ts的‘///’指令进行引入
//A.ts
namespace A{...}
//B.ts
namespace B{...}
//main.ts
///<reference path="A.ts" />
///<reference path="B.ts" />
let dahuang = new A.Cat('dahuang');
let xiaobai = new B.Cat('xiaobai');
//编译到一个文件中
//tsc --outfile index.js A.ts B.ts main.ts
有或者直接使用刚刚提到的外部模块,将多文件以模块的形式进行导出引入
//A.ts
export namespace A{...}
export namespace C{...}
//B.ts
export namespace B{...}
//main.ts
import {A,C} from './A';
import {B} from './B';
这里说一声,在一些教程里说三斜线操作符在3.0+版本后不支持了,亲自试了一下3.8.3版本是没有问题的,后来又翻了下官方文档,不支持的应该是///amd模块引用的这个指令,而不是所有的三斜线运算符都搞掉了