第4章:对象与接口
类型别名(Type Alias)与接口的区别
在 TypeScript 中,类型别名(type)和接口(interface)是定义复杂类型的两种主要方式。虽然它们的功能有许多重叠之处,但在设计理念和使用场景上存在显著差异。本节将详细对比二者的特性,帮助开发者根据实际需求选择更合适的工具。
1. 基本语法对比
类型别名(Type Alias)
type User = {
id: number;
name: string;
email?: string; // 可选属性
};
接口(Interface)
interface User {
id: number;
name: string;
email?: string; // 可选属性
}
2. 核心区别
扩展性
接口:
支持通过extends继承其他接口,适合构建层次化的类型系统:interface Admin extends User { permissions: string[]; }类型别名:
使用交叉类型(&)实现类似扩展的效果:type Admin = User & { permissions: string[] };
声明合并
接口:
允许同名接口自动合并(Declaration Merging):interface User { role: string; } interface User { age: number; } // 最终 User 包含 id, name, role, age类型别名:
同名类型别名会报错,不允许重复定义。
适用场景
接口:
更适合定义对象的形状(如 API 响应、组件 Props),尤其在需要扩展或实现类时。类型别名:
更适合组合复杂类型(如联合类型、元组、映射类型):type Status = "pending" | "completed" | "failed"; type Coordinates = [number, number];
3. 性能与设计哲学
接口:
在类型检查时会被视为“实体”,能提供更清晰的错误信息(如提示缺失的属性)。类型别名:
是纯粹的别名引用,适用于需要简化的复杂类型表达式。
4. 何时选择?
| 场景 | 推荐选择 |
|---|---|
| 需要继承或实现类 | 接口 (interface) |
| 需要声明合并 | 接口 (interface) |
| 组合联合类型或元组 | 类型别名 (type) |
| 定义函数或复杂工具类型 | 类型别名 (type) |
5. 示例:实际应用对比
// 使用接口的场景
interface APIResponse<T> {
data: T;
status: number;
}
// 使用类型别名的场景
type Nullable<T> = T | null;
type Callback = (err: Error | null, result?: string) => void;
总结
- 优先使用接口:当需要面向对象设计或扩展性时(如公共库的类型定义)。
- 优先使用类型别名:当需要灵活性或组合类型时(如工具函数、状态管理)。
理解二者的差异后,开发者可以更高效地利用 TypeScript 的类型系统,写出更具维护性的代码。
