TypeScript 中的模块与命名空间
模块
在 TypeScript 中,模块是一种封装和组织代码的方式。通过使用export
和import
关键字,我们可以定义模块并在不同的文件之间共享代码。
导出模块成员
使用export
关键字可以将模块中的变量、函数、类等成员导出,使其可以在其他模块中访问。
// math.ts
export function add(a: number, b: number): number {
return a + b;
}
export const PI = 3.14159;
在上面的示例中,我们导出了add
函数和PI
常量,以便其他模块可以使用它们。
导入模块成员
使用import
关键字可以导入其他模块中导出的成员。
// main.ts
import { add, PI } from './math';
console.log(add(2, 3)); // 输出: 5
console.log(PI); // 输出: 3.14159
在上面的示例中,我们从math
模块导入了add
函数和PI
常量,并在当前模块中使用它们。
默认导出
除了命名导出外,TypeScript 还支持默认导出。每个模块只能有一个默认导出,使用export default
关键字来定义。
// greeting.ts
export default function hello(name: string): string {
return `Hello, ${name}!`;
}
导入默认导出时,可以使用任意名称:
// main.ts
import greet from './greeting';
console.log(greet('Alice')); // 输出: Hello, Alice!
命名空间
命名空间是 TypeScript 中另一种组织代码的方式。它们提供了一种将相关的代码组合在一起的方法,避免了全局作用域的污染。
定义命名空间
使用namespace
关键字可以定义一个命名空间。
namespace MyNamespace {
export function foo(): void {
console.log('Hello from MyNamespace!');
}
}
在上面的示例中,我们定义了一个名为MyNamespace
的命名空间,并在其中导出了一个函数foo
。
嵌套命名空间
命名空间可以嵌套,以创建更细粒度的代码组织结构。
namespace OuterNamespace {
export namespace InnerNamespace {
export function bar(): void {
console.log('Hello from InnerNamespace!');
}
}
}
在上面的示例中,我们在OuterNamespace
中定义了一个嵌套的命名空间InnerNamespace
,并在其中导出了一个函数bar
。
使用命名空间中的成员
要使用命名空间中的成员,需要使用命名空间的名称作为前缀。
MyNamespace.foo(); // 输出: Hello from MyNamespace!
OuterNamespace.InnerNamespace.bar(); // 输出: Hello from InnerNamespace!
别名
为了避免每次使用命名空间成员时都需要输入完整的命名空间路径,我们可以使用import
关键字为命名空间创建别名。
import inner = OuterNamespace.InnerNamespace;
inner.bar(); // 输出: Hello from InnerNamespace!
在实际项目中,我通常根据代码的复杂度和组织需求来选择使用模块还是命名空间。对于需要在多个文件之间共享的代码,我倾向于使用模块;而对于在单个文件内部进行逻辑分组的代码,使用命名空间会更加方便。