Appearance
TypeScript 中的模块
在TypeScript中编写基于模块的代码时,有三个主要方面需要考虑:
- 语法:我想用什么语法来导入和导出东西?
- 模块解析:模块名称(或路径)和磁盘上的文件之间是什么关系?
- 模块输出目标:我编译出来的JavaScript模块应该是什么样子的?
ES模块语法
一个文件可以通过 export default 声明一个主要出口:
typescript
// @filename: hello.ts
export default function helloWorld() {
console.log("Hello, world!");
}
然后通过以下方式导入:
typescript
import hello from "./hello.js";
hello();
除了默认的导出,你还可以通过省略 default 的 export ,实现有一个以上的变量和函数的导出。
typescript
// @filename: maths.ts
export var pi = 3.14;
export let squareTwo = 1.41;
export const phi = 1.61;
export class RandomNumberGenerator {}
export function absolute(num: number) {
if (num < 0) return num * -1;
return num;
}
这些可以通过 import 语法在另一个文件中使用:
typescript
import { pi, phi, absolute } from "./maths.js";
console.log(pi);
// const absPhi: number
const absPhi = absolute(phi);
额外的导入语法
可以使用 import {old as new} 这样的格式来重命名一个导入:
typescript
import { pi as π } from "./maths.js";
// (alias)
var π: number
// import π
console.log(π);
你可以将上述语法混合并匹配到一个单一的 import 中:
typescript
// @filename: maths.ts
export const pi = 3.14;
export default class RandomNumberGenerator {}
// @filename: app.ts
import RNGen, { pi as π } from "./maths.js";
// (alias) class RNGen
// import RNGen
RNGen;
// (alias) const π: 3.14
// import π
console.log(π);
你可以把所有导出的对象,用 * as name ,把它们放到一个命名空间:
typescript
// @filename: app.ts
import * as math from "./maths.js";
console.log(math.pi);
// const positivePhi: number
const positivePhi = math.absolute(math.phi);
你可以通过 import "./file " 导入一个文件,而不把任何变量纳入你的当前模块:
typescript
// @filename: app.ts
import "./maths.js";
console.log("3.14");
在这种情况下, import 没有任何作用。然而, maths.ts 中的所有代码都被解析了,这可能引发影响其他对象的副作用。
typescript特定的ES模块语法
类型可以使用与JavaScript值相同的语法进行导出和导入。
typeScript
// @filename: animal.ts
export type Cat = { breed: string; yearOfBirth: number };
export interface Dog {
breeds: string[];
yearOfBirth: number;
}
// @filename: app.ts
import { Cat, Dog } from "./animal.js";
type Animals = Cat | Dog;
TypeScript用两个概念扩展了 import 语法,用于声明一个类型的导入。
- import type
这是一个导入语句,只能导入类型:
typescript
// @filename: animal.ts
export type Cat = { breed: string; yearOfBirth: number };
export type Dog = { breeds: string[]; yearOfBirth: number };
export const createCatName = () => "fluffy";
// @filename: valid.ts
import type { Cat, Dog } from "./animal.js";
export type Animals = Cat | Dog;
// @filename: app.ts
import type { createCatName } from "./animal.js";
const name = createCatName();
- 内联类型导入
TypeScript 4.5还允许以type为前缀的单个导入,以表明导入的引用是一个类型:
typescript
// @filename: app.ts
import { createCatName, type Cat, type Dog } from "./animal.js";
export type Animals = Cat | Dog;
const name = createCatName();
ES 模块语法与 CommonJS 行为
TypeScript 有 ES Module 语法,它直接与 CommonJS 和 AMD 的 require 相关联。使用 ES Module 的 import 在大多数情况下与这些环境的 require 相同,但这种语法确保你在 TypeScript 文件中与 CommonJS 的输出有1对1的匹配:
typescript
import fs = require("fs");
const code = fs.readFileSync("hello.ts", "utf8");