命名空间

命名空间就是之前的内部模块,任何以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模块引用的这个指令,而不是所有的三斜线运算符都搞掉了