文章目录
- 一、模块(Modules)
- 示例
- 二、命名空间(Namespaces)
- 示例
- 三、区别
一、模块(Modules)
在 TypeScript 中,任何包含顶级 import
或 export
声明的文件都被视为一个模块。模块的特点是它有自己的作用域,这意味着模块内的变量、函数、类等都是局部于该模块的,不会影响到全局作用域。
示例
假设我们有一个 1.ts
文件,定义了一个变量 a
:
const a = 1;
如果我们没有使用模块系统,而是在另一个文件中也声明了 a
,TypeScript 编译器会报错,提示变量重复声明。
要解决这个问题,我们可以使用 export
或 import
来引入模块系统:
const a = 10;
export default a;
在 TypeScript 中,export
关键字可以用来导出变量、函数、类或类型别名,其用法与 ES6 模块相同:
export const a = 1;
export type Person = {
name: string;
};
我们可以通过 import
语句来导入这些模块:
import { a, Person } from './export';
二、命名空间(Namespaces)
命名空间是 TypeScript 中的一个组织代码的方式,主要用于解决全局作用域下的命名冲突问题。通过命名空间,我们可以将相关的代码组织在一起,并且避免了全局污染。
示例
在 TypeScript 中,我们使用 namespace
关键字来定义命名空间:
namespace SomeNamespace {
export interface ISomeInterface { /* ... */ }
export class SomeClass { /* ... */ }
}
要在外部访问命名空间内的类和接口,我们需要在它们前面加上 export
关键字:
SomeNamespace.SomeClass;
命名空间在编译后的 JavaScript 中实际上是一个立即执行函数表达式(IIFE),它将相关的变量和函数组织在一个对象中:
var SomeNamespace;
(function (SomeNamespace) {
SomeNamespace.a = 1;
// ...
})(SomeNamespace || (SomeNamespace = {}));
三、区别
- 命名空间:
- 是一个全局对象,它通过一个名称来组织代码,以避免命名冲突。
- 在大型项目中可能导致全局命名空间污染,难以识别组件间的依赖关系。
- 通常用于通过
.d.ts
文件为 JavaScript 库定义类型。
- 模块:
- 可以包含代码和声明,并且可以声明其依赖关系。
- 模块内的代码具有局部作用域,不会污染全局作用域。
- 在 TypeScript 中是组织代码的首选方式,尤其是在大型应用中。
总结来说,模块是 TypeScript 中组织代码的首选方式,因为它提供了更好的封装和复用性。命名空间虽然仍然可用,但在新的 TypeScript 项目中通常不推荐使用,除非是在定义 JavaScript 库的类型时。