# TypeScript 与模块系统

URL: https://caijiao.org/ts/part3/module-system
Source: docs/ts/part3/module-system.md
Description: TypeScript 中的模块系统，涵盖 ES 模块和 CommonJS 模块的使用、类型声明文件（.d.ts）的作用、以及如何为第三方库提供类型支持。

在 [TypeScript](/ts/) 中，模块系统用于将代码拆分为多个文件，并通过导入和导出语法进行交互。TypeScript 支持多种模块规范，最常见的是 ES 模块和 CommonJS 模块。通过模块化开发，代码结构更加清晰，管理更加方便。

## ES 模块与 CommonJS

### ES 模块（ESM）

ES 模块是现代 JavaScript 标准的一部分，支持 `import` 和 `export` 语法。TypeScript 完全支持 ES 模块的语法。

#### 导出

```ts
// math.ts
export function add(x: number, y: number): number {
  return x + y;
}
```

#### 导入

```ts
// app.ts
import { add } from "./math";

console.log(add(2, 3));
```

TypeScript 会根据 `tsconfig.json` 配置的模块解析选项来处理模块。默认情况下，TypeScript 使用 ES 模块。

### CommonJS 模块

CommonJS 模块通常用于 Node.js 项目中，使用 `module.exports` 和 `require` 语法。虽然 TypeScript 支持 CommonJS，但我们更推荐使用 ES 模块。

#### 导出

```ts
// math.js
exports.add = function (x, y) {
  return x + y;
};
```

#### 导入

```ts
// app.js
const math = require("./math");

console.log(math.add(2, 3));
```

TypeScript 可以通过 `module` 配置来处理 CommonJS 模块。

## 类型声明文件（.d.ts）

类型声明文件用于为 JavaScript 库和模块提供类型定义。TypeScript 项目中，可以使用 `.d.ts` 文件来声明外部模块的类型，确保代码的类型安全。

### 示例：为 JavaScript 模块添加类型声明

假设我们有一个没有类型定义的 JavaScript 模块，使用 `.d.ts` 文件提供类型支持。

```ts
// utils.d.ts
declare module "utils" {
  export function sum(a: number, b: number): number;
  export function multiply(a: number, b: number): number;
}
```

### 使用第三方库的类型定义

很多流行的 JavaScript 库（如 jQuery、Lodash 等）都提供了 TypeScript 类型声明。你可以通过 `@types` 包来安装这些类型定义。

```bash
npm install --save-dev @types/lodash
```

安装后，TypeScript 会自动使用对应的类型声明文件。

## 第三方库的类型：@types 和 DefinitelyTyped

在 TypeScript 中，第三方 JavaScript 库的类型声明文件通常存储在 **DefinitelyTyped** 仓库中。你可以通过 `npm` 安装类型声明，通常使用 `@types` 前缀。

例如，安装 Lodash 的类型声明文件：

```bash
npm install --save-dev @types/lodash
```

通过这种方式，你可以为常用的 JavaScript 库提供强大的类型支持。

## 模块解析与路径别名

通过 TypeScript 配置文件（`tsconfig.json`）中的 `baseUrl` 和 `paths` 属性，可以为模块设置路径别名，使得导入模块时更加简洁和易读。

### 示例：路径别名配置

```json
{
  "compilerOptions": {
    "baseUrl": "./src",
    "paths": {
      "@utils/*": ["utils/*"]
    }
  }
}
```

### 使用路径别名

```ts
import { add } from "@utils/math";
```

通过设置路径别名，你可以避免复杂的相对路径，使得代码结构更加清晰。
