TypeScript里,可以使用命名空间(之前叫做“内部模块”,现在叫做“命名空间”)来组织你的代码。
Validation.ts
export interface StringValidator {
isAcceptable(s: string): boolean;
}
LettersOnlyValidator.ts
import { StringValidator } from "./Validation"; const lettersRegexp = /^[A-Za-z]+$/;
export class LettersOnlyValidator implements StringValidator {
isAcceptable(s: string) { return lettersRegexp.test(s);
}
}
ZipCodeValidator.ts
import { StringValidator } from "./Validation"; const numberRegexp = /^[0-9]+$/; class ZipCodeValidator implements StringValidator {
isAcceptable(s: string) {
return s.length === 5 && numberRegexp.test(s);
}
}
export { ZipCodeValidator };
export { ZipCodeValidator as mainValidator };
/// <reference path="Validation.ts" /> /// <reference path="LettersOnlyValidator.ts" /> /// <reference path="ZipCodeValidator.ts" /> let strings = ["Hello", "98052", "101"];
let validators: { [s: string]: Validation.StringValidator; } = {};
validators["ZIP code"] = new Validation.ZipCodeValidator();
validators["Letters only"] = new Validation.LettersOnlyValidator();
strings.forEach(s => { for (let name in validators) { console.log("\"" + s + "\"" + (validators[name].isAcceptable(s) ? " matches " : " does not match ") + name);
}
});
简化命名空间操作的方法是别名,使用 import q = x.y.z 给常用的对象起一个短的名字,可以用这种方法为任意标识符创建别名,也包括导入的模块中的对象。
namespace Shapes {
export namespace Polygons {
export class Triangle { }
export class Square { }
}
}
import polygons = Shapes.Polygons; let sq = new polygons.Square();
为了描述不是用TypeScript编写的类库的类型,需要声明类库导出的 API。 由于大部分程序库只提供少数的顶级对象,命名空间是用来表示它们的一个好办法。
D3.d.ts
declare namespace D3 {
export interface Selectors {
select: {
(selector: string): Selection;
(element: EventTarget): Selection;
};
}
export interface Event {
x: number;
y: number;
}
export interface Base extends Selectors {
event: Event;
}
}
declare let d3: D3.Base;
在TypeScript 里,可以使用模块与命名空间来组织代码的方法。
使用命名空间
命名空间是位于全局命名空间下的一个普通的带有名字的 JavaScript 对象,这令命名空间十分容易使用。 它们可以在多文件中同时使用,并通过 —outFile 结合在一起。 命名空间是组织 Web 应用不错的方式,但就像其它的全局命名空间污染一样,它很难去识别组件之间的依赖关系,尤其是在大型的应用中。
使用模块
像命名空间一样,模块可以包含代码和声明。 不同的是模块可以 声明它的依赖。模块会把依赖添加到模块加载器上(例如 CommonJs / Require.js)。 对于小型的 Web 应用来说可能没必要,但是对于大型应用,这一点点的花费会带来长久的模块化和可维护性上的便利。 模块也提供了更好的代码重用,更强的封闭性以及更好的使用工具进行优化。
从ECMAScript 2015开始,模块成为了语言内置的部分,应该会被所有正常的解释引擎所支持。 因此,对于新项目来说推荐使用模块做为组织代码的方式。