TypeScript学习(十八):模块与命名空间 | 八月更文挑战

321 阅读2分钟

这是我参与8月更文挑战的第4天,活动详情查看:8月更文挑战

使用模块

模块包括代码与声明

模块可以提供更好的代码复用,代码隔离与更好的打包工具支持。对于 Node 应用,优先推荐使用模块,而非命名空间。从  ES6 开始,JS 有了模块系统,并且已由编译器实现。

使用命名空间

命名空间是 TS 特定的组织代码的方式。命名空间们本质上知识多个简单的 JS 对象。因此可以很方便地使用命名空间。相同的命名空间可以分散在多文件中,并且通过 --outFile 连接起来。在 Web 应用中,命名空间可以很好地用来组织代码。产生的依赖文件可以使用

但是,在一个大型的应用中,命名空间难以区分项目各个组件的依赖。

模块与命名空间的行为区别

在模块中使用 ///

错误行为:使用 /// 语法去导入一个模块。模块只能通过 import 语法导入。

但是,如果是一个非模块文件,比如单纯的声明文件,可以使用 /// 语法导入。

someModule.ts

// 非模块文件
declare module "someModule"{
    export function (): string;
}

index.ts

/// <reference path="someModule.ts">
import * as m from "SomeModule";

此时,/// 用以定位生命文件。

不必要的命名空间

下方 shape.ts 中使用了命名空间,在使用的时候,容易造成理解困难,为什么是shapes.Shapes?

shape.ts

export namespace Shapes {  export class Triangle {    /* ... */  }  export class Square {    /* ... */  }}

shapeConsumer.ts

import * as shapes from "./shapes";let t = new shapes.Shapes.Triangle(); // shapes.Shapes?

在 TS 中,模块的特点之一是:模块的消费者在使用模块的时候,就会给其指定名称。因此没有必要再给导出对象包裹一层命名空间。

并且使用命名空间的情况一般是提供一个本地的代码逻辑区块以防止命名冲突。
模块文件本身就是一个大的代码块,其顶级名称是由模块消费者定义的,也就么有必要在模块外部包裹一层命名空间。

因此代码可以修改成如下:

shape.ts

export class Triangle {    /* ... */  }  
export class Square {    /* ... */  }

index.ts

import * as shapes from "./shapes";let t = new shapes.Triangle();