# 第7章:模块与命名空间
## 模块与命名空间的对比
在 TypeScript 中,模块(Modules)和命名空间(Namespaces)都是用于组织代码结构的工具,但它们的适用场景和设计理念存在显著差异。本节将详细对比二者的特性,帮助开发者根据实际需求选择合适的方式。
### 1. **设计目标**
- **模块**
基于 ES6 模块标准(`import/export`),强调文件级别的隔离和依赖管理,适用于现代前端工程化项目。模块通过文件路径解析依赖,天然支持静态分析和 Tree Shaking。
- **命名空间**
TypeScript 早期提供的代码组织方案,通过 `namespace` 关键字将相关代码逻辑包裹在全局作用域内。适用于小型项目或需要避免全局污染的传统脚本环境。
### 2. **作用域隔离**
| 特性 | 模块 | 命名空间 |
|---------------|-------------------------------|------------------------------|
| **作用域** | 文件级作用域(需显式导出/导入)| 全局或嵌套作用域 |
| **污染风险** | 无 | 可能污染全局(需配合 IIFE) |
### 3. **依赖管理**
- **模块**
显式声明依赖关系,通过文件路径引用其他模块:
```typescript
// math.ts
export function add(a: number, b: number) { return a + b; }
// app.ts
import { add } from './math';
- 命名空间
依赖通过全局命名空间隐式合并,需手动管理加载顺序:namespace MathUtils { export function add(a: number, b: number) { return a + b; } } // 直接调用 MathUtils.add(1, 2);
4. 适用场景对比
| 场景 | 推荐方案 | 原因 |
|---|---|---|
| 大型应用/组件库 | 模块 | 更好的可维护性、支持按需加载 |
| 旧代码迁移/脚本增强 | 命名空间 | 兼容性高,无需重构文件结构 |
| 与第三方库交互 | 模块 | 主流库(如 React、Lodash)均提供模块化支持 |
5. 混合使用注意事项
TypeScript 允许模块内使用命名空间,但通常不推荐:
// 不推荐的做法
import * as React from 'react';
namespace MyComponent {
export const Button = () => <React.Button />;
}
最佳实践:优先使用模块化方案,仅在遗留代码或特殊需求(如全局类型扩展)时选择命名空间。
总结表格
| 维度 | 模块 | 命名空间 |
|---|---|---|
| 标准化 | ES6 标准 | TypeScript 特有 |
| 作用域 | 文件级 | 全局/嵌套 |
| 适用规模 | 中大型项目 | 小型脚本或遗留系统 |
| 工具链支持 | 完善(Webpack/Rollup 等) | 有限 |
此内容通过对比表、代码示例和场景分析,清晰区分了模块与命名空间的核心差异,同时提供了实践建议。