TypeScript 命名空间、模块区别

462 阅读3分钟

一 区别

  • 命名空间是位于全局命名空间下的一个普通的带有名字的  JavaScript  对象,使用起来十分容易。但就像其它的全局命名空间污染一样,它很难去识别组件之间的依赖关系,尤其是在大型的应用中
  • 像命名空间一样,模块可以包含代码和声明。不同的是模块可以声明它的依赖
  • 在正常的TS项目开发过程中并不建议用命名空间,但通常在通过 d.ts 文件标记 js 库类型的时候使用命名空间,主要作用是给编译器编写代码的时候参考使用

二、命名空间

  命名空间一个最明确的目的就是解决重名问题。

  命名空间定义了标识符的可见范围,一个标识符可在多个名字空间中定义,它在不同名字空间中的含义是互不相干的。这样,在一个新的名字空间中可定义任何标识符,它们不会与任何已有的标识符发生冲突,因为已有的定义都处于其他名字空间中。

  TypeScript 中命名空间使用 namespace 来定义,语法格式如下:

namespace SomeNameSpaceName { 
   export interface ISomeInterfaceName {      }  
   export class SomeClassName {      }  
}

  以上定义了一个命名空间 SomeNameSpaceName,如果我们需要在外部可以调用 SomeNameSpaceName 中的类和接口,则需要在类和接口添加 export 关键字。

  要在另外一个命名空间调用语法格式为:SomeNameSpaceName.SomeClassName;

  如果一个命名空间在一个单独的 TypeScript 文件中,则应使用三斜杠 /// 引用它,语法格式如下:

 /// <reference path = "SomeFileName.ts" /> 

  命名空间支持嵌套,即你可以将命名空间定义在另外一个命名空间里头。

namespace namespace_name1 { 
    export namespace namespace_name2 {
        export class class_name {    } 
    } 
}

  成员的访问使用点号 . 来实现。

三、模块

  TypeScript 模块的设计理念是可以更换的组织代码。模块是在其自身的作用域里执行,并不是在全局作用域,这意味着定义在模块里面的变量、函数和类等在模块外部是不可见的,除非明确地使用 export 导出它们。类似地,我们必须通过 import 导入其他模块导出的变量、函数、类等。

  两个模块之间的关系是通过在文件级别上使用 import 和 export 建立的。模块使用模块加载器去导入其它的模块。在运行时,模块加载器的作用是在执行此模块代码前去查找并执行这个模块的所有依赖。大家最熟知的JavaScript模块加载器是服务于 Node.js 的 CommonJS 和服务于 Web 应用的 Require.js。此外还有有 SystemJs 和 Webpack。

  模块导出使用关键字 export 关键字,语法格式如下:

// 文件名 : SomeInterface.ts 
export interface SomeInterface { 
   // 代码部分
}

// 要在另外一个文件使用该模块就需要使用 import 关键字来导入:
import someInterfaceRef = require("./SomeInterface");