TypeScript 模块
TS 使用和 JS 一样的 ES 模块系统(import/export),但额外提供了类型导入导出的能力——把"值"和"类型"区分开。这一章讲清楚 TS 模块的写法,重点是 import type 这个 TS 独有的语法。
1. 模块基础
在 TS 里,每个 .ts 文件默认就是一个模块,有自己的独立作用域。要用别的文件里的东西,必须先导出,再导入——和 JS 的 ESM 完全一样:
// user.ts —— 一个模块文件
// 每个 .ts 文件默认就是一个模块(有自己的作用域)
// 1. 命名导出:导出值
export const defaultName = "匿名";
export function greet(name: string): string {
return `你好, ${name}`;
}
// 2. 导出类型(interface、type)
export interface User {
id: number;
name: string;
}
export type ID = number | string;
// 3. 默认导出:每个模块最多一个
export default class UserService {
getUser(id: number): User {
return { id, name: "默认用户" };
}
}2. 导入
导入也和 JS 一致:命名导入用花括号,默认导入不用花括号:
// app.ts —— 导入上面的模块
// 1. 导入命名导出
import { greet, defaultName } from "./user";
// 2. 导入默认导出(不用花括号,可以重命名)
import UserService from "./user";
// 3. 一次性导入所有
import * as UserModule from "./user";
// 4. 用起来
console.log(greet("小明"));
console.log(defaultName);
const svc = new UserService();3. import type / export type(TS 独有)
这是 TS 相比 JS 最重要的模块增强。类型在运行时会被擦除,所以有时你需要明确告诉编译器:"这个东西是纯类型,不要打包到运行时代码里"。用 import type 就能做到:
// TS 特有:import type / export type
// 只导入/导出类型(运行时会被擦除),用于明确区分值和类型
import type { User, ID } from "./user"; // 只导入类型
import { greet } from "./user"; // 导入值
// 也可以在一个 import 里混用
import { greet, type User } from "./user";
// 导出端:export type
export type { User } from "./user"; // 只重导出类型
// 用 import type 的好处:
// 1. 让编译器/打包工具知道这是纯类型,可以安全擦除
// 2. 避免"类型出现在运行时"的循环依赖问题实战中推荐养成习惯:只用作类型的导入,加 type 关键字。这样打包工具能更高效地擦除类型,也能避免一些循环依赖的诡异问题。
4. barrel 模式(汇总导出)
项目里常有这样的结构:一个目录下有很多模块,用一个 index.ts 统一汇总导出。这种模式叫 barrel(桶),让外部导入更简洁:
// barrel 模式:用一个 index.ts 汇总所有导出
// user.ts
export interface User { id: number; name: string; }
// post.ts
export interface Post { title: string; }
// index.ts(汇总)
export * from "./user";
export * from "./post";
// 外部使用时只需从 index 导入
import { User, Post } from "./models"; // 等价于从 index.ts 导入这是大型项目组织代码的标准做法,几乎所有 TS 库(如 Vue、React)都用。
5. ES 模块 vs CommonJS
JS 历史上有两套模块系统:ESM(import/export,新标准)和 CommonJS(require/module.exports,Node 老标准)。TS 默认用 ESM,但也能识别 CommonJS:
// TS 默认用 ES 模块(ESM),但也能识别 CommonJS
// CommonJS 是 Node 的老模块系统(require/module.exports)
const fs = require("fs"); // CommonJS 风格
module.exports = { name: "hi" };
// 在 TS 里推荐统一用 ESM(import/export)
// tsconfig 里设置 "module": "ESNext" 或 "NodeNext"
// 这样配合打包工具(Vite/Webpack)或新版 Node 都最顺新项目一律推荐 ESM。tsconfig 里把 module 设成 ESNext 或 NodeNext,配合打包工具或新版 Node,体验最好。
6. 解析策略:classic vs node
TS 怎么根据 import "./user" 找到具体文件,由 moduleResolution 配置决定:
"node"(旧):模拟 Node 的解析规则,找./user.ts、./user/index.ts。"bundler"/"nodenext"(新,推荐):更现代,配合 Vite/Webpack 等打包工具。
这部分会在 tsconfig 那一篇详讲。
小结
TS 模块 = JS 的 ESM + import type。核心要点:每个 .ts 文件是独立模块,用 import/export 互通,纯类型用 import type 区分。barrel 模式(index.ts 汇总)是大型项目的标准做法。下一篇讲 TS 日常开发最常用的工具类型(Partial/Record 等)。
← 上一篇 TypeScript 类
下一篇 TypeScript 工具类型 →