TypeScript 是 JavaScript 的超集,提供了强大的类型检查功能,帮助开发者编写更安全、更易维护的代码。其中,type 类型别名和 interface 接口声明是定义自定义类型的两种常用方式。它们看起来很相似,但实际上在设计目的和使用场景上有所不同。本文将介绍它们的主要区别、相似之处以及最佳实践。
什么是 type?
type 是类型别名,它可以为任意合法的 TypeScript 类型命名,包括基本类型、联合类型、元组,甚至接口。
type Point = {
x: number;
y: number;
};
type ID = string | number;
type 非常灵活,能够表示复杂的类型结构,例如联合类型和交叉类型:
type Shape = Circle | Rectangle;
type Circle = { kind: "circle"; radius: number };
type Rectangle = { kind: "rectangle"; width: number; height: number };
什么是 interface?
interface 用于定义对象的结构,主要用于描述类的契约,或可扩展的对象类型。
interface Point {
x: number;
y: number;
}
接口支持 声明合并(declaration merging),也就是说你可以多次声明同一个接口,TypeScript 会自动将它们合并:
interface Person {
name: string;
}
interface Person {
age: number;
}
// 合并后,Person 包含 name 和 age 属性
const user: Person = { name: "Alice", age: 30 };
核心区别对比
| 特性 | type 类型别名 | interface 接口 |
|---|---|---|
| 能否描述原始类型或联合类型 | ✅ 可以 | ❌ 不可以 |
| 能否定义元组 | ✅ 可以 | ❌ 不可以 |
| 是否支持声明合并 | ❌ 不支持 | ✅ 支持 |
| 能否扩展其他类型 | ✅ 使用 &(交叉类型) | ✅ 使用 extends |
| 能否被类实现(implements) | ✅ 可以 | ✅ 可以 |
| 是否推荐用于对象类型 | ✅ 推荐(灵活) | ✅ 推荐(尤其是公开 API) |
何时使用 type 或 interface
-
使用
interface的场景:- 定义对象的结构。
- 与类结合使用,定义接口契约。
- 希望接口可以被扩展或合并。
- 编写公开的 API 时。
-
使用
type的场景:- 需要使用联合类型或交叉类型组合。
- 定义基本类型、元组或复杂组合类型。
- 喜欢函数式、组合式的类型风格。
实际示例
// 使用 interface 定义对象结构
interface User {
id: number;
name: string;
}
// 使用 type 定义交叉类型
type Admin = User & {
role: "admin";
};
// 使用 type 定义联合类型
type Status = "pending" | "active" | "disabled";
总结
type 和 interface 都是 TypeScript 中定义类型的强大工具。一般来说:
- 对于公开的对象类型结构或面向类的设计,推荐使用
interface; - 对于更复杂的类型组合,例如联合、交叉、元组等结构,推荐使用
type。
掌握这两者的差异和使用时机,将帮助你编写更清晰、表达力更强的 TypeScript 代码。