TypeScript支持使用CommonJS和ES6模块系统的导入和导出,module.exports
是CommonJS用于导出模块的方式。
TypeScript的导出方式应该包括:
- 命名导出(Named Exports)
- 默认导出(Default Export)
- 混合导出(同时使用默认和命名)
- 重新导出(Re-export)
- 导出所有内容(Export All)
- 导出类型(Exporting Types)
- 导出命名空间(Namespaces)(不推荐,已逐渐被模块替代)
- 特殊导出语法(如export =和import = require)
TypeScript的导入方式应该包括:
- 使用ES6模块系统的导入
- 使用CommonJS导入
接下来我会通过例子来讲解TypeScript 中 导出(Export) 和 导入(Import) 的完整用法。
一、导出 与 导入
1. 命名导出(Named Export)
语法:
// 直接导出
export const PI = 3.14;
export function sum(a: number, b: number) { return a + b; }
// 先声明后导出
const PI = 3.14;
function sum(a: number, b: number) { return a + b; }
export { PI, sum }; // 支持重命名:export { PI as CirclePI }
示例导入:
// 导入直接导出的项
import { PI, sum } from './path/to/module';
console.log(PI); // 输出 3.14
console.log(sum(1, 2)); // 输出 3
// 导入先声明后导出的项
import { PI as CirclePI, sum as add } from './path/to/module'; //as表示在当前模块中重命名
console.log(CirclePI); // 输出 3.14
console.log(add(1, 2)); // 输出 3
特点:
- 一个模块可导出多个值。
- 导入时需要明确指定名称(或通过解构)。
2. 默认导出(Default Export)
语法:
// 直接导出默认值
export default function greet() { console.log("Hello!"); }
// 先声明后导出
class Logger { /* ... */ }
export default Logger;
示例导入:
import customGreet from './path/to/greet';
customGreet(); // 输出 "Hello!"
import MyLogger from './path/to/logger';
let logger = new MyLogger();
特点:
- 每个模块仅能有一个默认导出。
- 导入时可自定义名称,无需花括号:
import MyLogger from './path/to/logger';
。
3. 混合导出(Named + Default)
语法:
// utils.ts
export default function log(message: string) { console.log(message); }
export const VERSION = "1.0";
示例导入:
import log, { VERSION } from './utils';
特点:
- 可以在一个导入语句中同时获取默认导入和命名导入的项,是代码更加简洁和易于管理
4. 重新导出(Re-export)
语法:
// math.ts
const add = (a: number, b: number) => a + b;
export { add };
export default class MathUtils {
static multiply(a: number, b: number) { return a * b; }
}
// index.ts
export { add as sum } from './math'; // 从math.ts中导入add并重命名为sum后导出
export * from './math'; // 导出math.ts中所有的命名导出项
export { default } from './math'; // 导出math.ts中的默认导出项
5. 类型导出
语法:
// 导出类型
export type User = { id: number; name: string };
// 导出接口
export interface Product { sku: string; price: number; }
// 单独导出类型
type User = { id: number };
export type { User };
6、特殊导出语法
在TypeScript中,为了兼容CommonJS模块系统,可以使用一些特殊的导出语法。以下是一些常见的用法:
-
导出默认值:
module.exports = 3.142;
-
导出命名值:
exports.PI = 3.142; exports.sum = (a: number, b: number) => a + b;
-
混合导出:可以同时导出默认值和命名值,但需要注意 CommonJS 和 ES6 模块系统之间的差异。
以下是一个综合示例,展示了如何在TypeScript中使用CommonJS兼容的特殊导出语法:
假设math.ts
的内容如下:
// math.ts
const add = (a: number, b: number) => a + b;
const multiply = (a: number, b: number) => a * b;
exports.PI = 3.142;
exports.add = add;
exports.multiply = multiply;
module.exports = {
PI: 3.142,
add: add,
multiply: multiply
};
在index.ts
中,你可以使用这些CommonJS兼容的导出语法:
// index.ts
module.exports = require('./math').PI; // 导出默认值为math.ts中的PI
exports.sum = require('./math').add; // 导出命名值sum为math.ts中的add函数
exports.multiply = require('./math').multiply; // 导出命名值multiply为math.ts中的multiply函数
或者混合导出:
// index.ts
const math = require('./math');
module.exports = math; // 导出整个math模块
这样,其他模块在导入时可以使用require
函数来导入这些CommonJS模块:
// 使用require导入
const mathModule = require('./index');
console.log(mathModule.PI); // 输出 3.142
console.log(mathModule.sum(1, 2)); // 输出 3
console.log(mathModule.multiply(2, 3)); // 输出 6
总结上述例子所说的:
module.exports
:用于导出默认值。exports.PI
:用于导出命名值。require('./math')
:用于导入CommonJS模块。
需要注意的是,TypeScript通常推荐使用ES6模块系统的导入和导出语法,以保持代码的一致性和现代性。
方法总结
导出方式 | 语法示例 | 导入方式 | 适用场景 |
---|---|---|---|
命名导出 | export const PI = 3.14; | import { PI } from './math'; | 多功能模块、工具库 |
默认导出 | export default class User {} | import User from './user'; | 单例、组件、核心功能 |
混合导出 | export default log; export const VERSION; | import log, { VERSION } from './utils'; | 主功能+辅助工具 |
重新导出 | export * from './math'; | import { add } from './utils'; | 模块聚合入口 |
类型导出 | export type User = { ... }; | import type { User } from './types'; | 类型共享 |
二、注意事项
1. 导出规范
- 优先使用命名导出:便于 Tree Shaking 和 IDE 跳转。
- 默认导出仅用于主功能:如 React 组件、配置对象。
- 避免混合导出类型和值:使用
export type
明确分离。
2. 导入规范
- 明确导入路径:使用相对路径(
./
或../
)或绝对路径别名。 - 按需导入:避免
import * as
导致加载未用代码。 - 类型与运行时分离:
import { fetchData } from './api'; // 运行时依赖
import type { DataType } from './types'; // 类型依赖
3.常见错误示例
错误场景 | 正确写法 |
---|---|
混淆默认导出和命名导入 | import MyModule from './module'; (默认导出)import { MyModule } from './module'; (命名导出) |
未导出类型导致运行时错误 | 使用 export type 或 import type 。 |
动态导入未使用 await | const module = await import('./math'); |