TypeScript 中接口(interface)专用于描述对象结构与契约,支持继承、声明合并和类实现;类型别名(type)则更灵活,可表示任意类型,适合联合、映射、泛型等复杂场景。

在 TypeScript 中,接口(interface)和类型别名(type)都用于定义类型,但设计意图、语法能力和适用场景有明确区分——不是“哪个更好”,而是“哪个更合适”。
接口:描述对象结构与契约
接口专为“描述对象的形状”而生,强调可扩展性、继承性和协作契约。它天然支持声明合并、类实现和面向接口编程。
- 用
interface关键字定义,只适用于对象类型(不能表示原始类型或联合类型) - 支持
extends继承多个接口:
interface Admin extends User, Permission { role: 'admin' } - 支持声明合并:同名接口会自动合并成员,适合模块化扩展
interface Config { timeout: number }
interface Config { retries: number } // 合并后 Config 同时含 timeout 和 retries - 可用于约束类:
class UserService implements UserInterface { ... } - 支持多种签名:属性、方法、调用签名、构造签名、索引签名等
interface EventMap { click: MouseEvent; input: InputEvent }
interface Emitter { on(type: K, handler: (e: EventMap[K]) => void): void }
类型别名:灵活表达任意类型
类型别名用 type 声明,本质是给类型起一个新名字,能力更泛化,适合组合、映射和元编程场景。
- 可表示任何类型:基本类型、联合类型、交叉类型、元组、函数、映射类型、条件类型等
type ID = string | number;
type Status = 'idle' | 'loading' | 'success';
type UserRecord = Record; - 通过
&实现“组合式扩展”,而非继承:
type Animal = { name: string };
type Dog = Animal & { bark(): void }; - 支持递归定义(接口不支持直接递归):
type Tree= { value: T; children?: Tree [] }; - 适合与泛型、工具类型配合:
type ApiResponse= { data: T; success: boolean } & (T extends null ? { error: string } : {});
怎么选:看用途,不看语法糖
没有绝对优劣,关键看你要解决什么问题:
立即学习“Java免费学习笔记(深入)”;
- 要定义一个供多个类实现、或跨文件逐步补充的对象结构?→ 优先用 interface
- 要表达联合值(如状态枚举)、映射类型、函数签名别名或复杂条件逻辑?→ 必须用 type
- 想让别人能轻松地为你的类型添加字段(比如插件扩展配置)?→ 用 interface(靠声明合并)
- 需要定义一个不可变的语义化基础类型(如
type UserID = string)?→ 用 type 更清晰
小提醒:编译后都消失
无论 interface 还是 type,它们只存在于 TypeScript 编译阶段,生成的 JavaScript 中不会留下任何痕迹。它们的作用纯粹是为开发过程提供类型检查、智能提示和重构保障。


















