namespace vs module

在 TypeScript 1.5 版本之前, TS 中存在 内部模块外部模块 的概念。但是从 1.5 开始,为了兼容 ES6 中的模块语法,将 内部模块 改为了 命名空间。而 外部模块 则称为 模块,此时的 模块(module) 概念与 ES6 中的 模块 保持一致。

namespace 介绍

namespace 的概念与module 非常相似,主要都用于组织代码。在实际的开发中推荐尽量使用 module 来满足需求。

namespace 引用方式

需要注意的是,namespace 之间引用的时候, 采用 /// <reference path="namespaceName.ts" /> 的语法来互相引用,而不遵循 moduleimport 规范。

namespace 主要场景

namespace 可以用于组织代码,聚合多个类等场景,但是此种场景推荐使用 ES6 module。不过当我们需要在类型声明文件(*.d.ts)中描述一个带有多个函数和属性的第三方库的时候,会使用到 namespace 。例如下方例子:

  1. /*~ If your library has properties exposed on a global variable,
  2. *~ place them here.
  3. *~ You should also place types (interfaces and type alias) here.
  4. */
  5. declare namespace myLib {
  6. //~ We can write 'myLib.timeout = 50;'
  7. let timeout: number;
  8. //~ We can access 'myLib.version', but not change it
  9. const version: string;
  10. //~ There's some class we can create via 'let c = new myLib.Cat(42)'
  11. //~ Or reference e.g. 'function f(c: myLib.Cat) { ... }
  12. class Cat {
  13. Ï;
  14. constructor(n: number);
  15. //~ We can read 'c.age' from a 'Cat' instance
  16. readonly age: number;
  17. //~ We can invoke 'c.purr()' from a 'Cat' instance
  18. purr(): void;
  19. }
  20. //~ We can declare a variable as
  21. //~ 'var s: myLib.CatSettings = { weight: 5, name: "Maru" };'
  22. interface CatSettings {
  23. weight: number;
  24. name: string;
  25. tailLength?: number;
  26. }
  27. //~ We can write 'const v: myLib.VetID = 42;'
  28. //~ or 'const v: myLib.VetID = "bob";'
  29. type VetID = string | number;
  30. //~ We can invoke 'myLib.checkCat(c)' or 'myLib.checkCat(c, v);'
  31. function checkCat(c: Cat, s?: VetID);
  32. }