在JavaScript程序中,通常使用“命名空间”来组织并隔离代码以免产生命名冲突等问题,最为流行的实现命名空间的方法是使用立即执行的函数表达式。
TypeScript利用了这个经典的命名空间实现方式并提供了声明命名空间的简便语法
命名空间通过namespace关键字来声明,它相当于一种语法糖
namespace Utils {
function isString(val:any){
return typeof val === 'string'
}
}
在定义命名空间的名字时允许使用以点符号“.”分隔的名字
namespace System.Utils {
function isString(value: any) {
return typeof value === 'string';
}
}
同等于
namespace System {
export namespace Utils {
function isString(value: any) {
return typeof value === 'string';
}
}
}
默认情况下,在命名空间内部的声明只允许在该命名空间内部使用,在命名空间之外访问命名空间内部的声明会产生错误
如果想要让命名空间内部的某个声明在命名空间外部也能够使用,则需要使用导出声明语句明确地导出该声明
namespace Utils {
export function isString(value: any) {
return typeof value === 'string';
}
}
Utils.isString()
我们可以使用import语句为命名空间的导出声明起一个别名,当命名空间名字比较长时,使用别名能够有效地简化代码。
namespace Utils {
export function isString(value: any) {
return typeof value === 'string';
}
}
namespace App {
import isString = Utils.isString;
isString('yes');
Utils.isString('yes');
}
我们可以将同一个命名空间声明拆分到不同的文件中,TypeScript最终会将同名的命名空间声明合并在一起
// a.ts
namespace Utils {
export function isString(value: any) {
return typeof value === 'string';
}
export interface Point {
x: number;
}
}
//b.ts
namespace Utils {
export function isNumber(value: any) {
return typeof value === 'number';
}
}
最终,合并后的Utils命名空间中存在三个导出声明isString、isNumber和Point
当我们将命名空间拆分到不同的文件后,需要注意文件的加载顺序,因为文件之间可能存在依赖关系
// a.ts
namespace App {
export function isString(value: any) {
return typeof value === 'string';
}
}
// b.ts
namespace App {
const a = isString('foo');
}
从上面的代码可以看出 b.ts 依赖于 a.ts,因为“b.ts”中调用了“a.ts”中定义的方法,我们需要保证“a.ts”先于“b.ts”被加载,否则在执行“b.ts”中的代码时将产生isString未定义的错误。
定义文件间的依赖关系有多种方式:
{
"compilerOptions": {
"strict": true,
"target": "ESNext",
"outFile": "main.js"
},
"files": ["a.ts", "b.ts"]
}
///
上面这行代码声明依赖关系,即该三斜线后面的代码都依赖a.ts文件
除了上面的这种三斜线以外还有其他形式的三斜线指令,实际上三斜线指令是一系列指令的统称,它是从TypeScript早期版本就开始支持的编译指令。
目前,已经不推荐继续使用三斜线指令,因为可以使用模块来取代它的大部分功能.
接下来再了解一下其他的三斜线指令
///
该三斜线指令用来定义对某个DefinitelyTyped声明文件的依赖,或者说是对安装在“node_modules/@types”目录下的某个声明文件的依赖
types”属性的值是声明文件安装包的名称,也就是安装到“node_modules/@types”目录下的文件夹的名字
///
该三斜线指令用于定义对语言内置的某个声明文件的依赖