TypeScript - 模块 和 命名空间

120 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第16天,点击查看活动详情

模块

JavaScript 规范声明任何没有 export 的 JavaScript 文件都应该被认为是一个脚本,而非一个模块

在一个脚本文件中,变量和类型会被声明在共享的全局作用域,将多个输入文件合并成一个输出文件,或者在 HTML使用多 个 <script> 标签加载这些文件

如果你有一个文件,现在没有任何 import 或者 export,但是你希望它被作为模块处理,需要添加export {} 以将当前文件转换为模块

interface IFoo {}
type Type = {}

// 单独形成一个独立的模块 避免类型定义冲突
export {}

内置类型导入

从TypeScript 4.5开始也允许单独导入TypeScript的类型描述, 需要使用 type 前缀 ,表明被导入的是一个类型

虽然在实际导入类型的时候,不写type 也是合法的

但是type可以让一个非 TypeScript 编译器比如 Babel 或者 Esbuild, SWC 知道什么样的导入可以被安全移除,从而提高TS编译为JS的效率

type.ts

export interface IFoo {}
export type IType = {}

index.ts

// 在导入的内容之前加上type 表示引入的是一个类型
// import { type IFoo, type IType} from './type'

// 也可以在整个导入块之前 加上type 表示引入的全部都是类型
import type { IFoo, IType } from "./type";

命令空间

在 ES 模块标准之前出现TypeScript有它自己的模块格式,名为namespaces

命名空间在TypeScript早期时,称之为内部模块,目的是将一个模块内部再进行作用域的划分,防止一些命名冲突的问题

虽然命名空间没有被废弃,但是由于 ES 模块已经拥有了命名空间的大部分特性,因此更推荐使用 ES 模块,这样才能与 JavaScript 的(发展)方向保持一致

// @filename type.ts
export namespace Time {
  // 每个命名空间的内部是一个单独的模块
  export function format() {
    console.log('format time')
  }
}

export namespace Price {
  export function format() {
    console.log('format price')
  }
}
// @filename index.ts
import { Price, Time } from "./type";

Price.format()
Time.format()