在 TypeScript 中,type
和 interface
都用于定义类型,并且在许多情况下它们是可以互换使用的。然而,它们有一些关键的区别和各自的适用场景。在深入理解 type
和 interface
之前,先看看它们的基本用法。
1. 基本用法:type
和 interface
定义对象类型
// 使用 interface
interface User {
name: string;
age: number;
}
// 使用 type
type UserType = {
name: string;
age: number;
};
const user1: User = { name: "Alice", age: 25 };
const user2: UserType = { name: "Bob", age: 30 };
在这个例子中,interface
和 type
都可以定义一个对象类型,并且在使用上几乎没有区别。
2. 扩展(Extend)
2.1 interface
的扩展
interface
可以通过继承的方式进行扩展:
interface User {
name: string;
age: number;
}
interface Admin extends User {
role: string;
}
const admin: Admin = {
name: "Alice",
age: 30,
role: "Administrator",
};
2.2 type
的扩展
type
可以通过交叉类型(Intersection Types)来扩展:
type UserType = {
name: string;
age: number;
};
type AdminType = UserType & {
role: string;
};
const adminType: AdminType = {
name: "Bob",
age: 35,
role: "Admin",
};
区别:
-
interface
使用extends
关键字进行继承扩展。 -
type
使用&
交叉类型进行扩展。
3. 合并声明(Declaration Merging)
3.1 interface
的声明合并
interface
允许重复声明,TypeScript 会自动合并它们的成员。
interface User {
name: string;
}
interface User {
age: number;
}
const user: User = { name: "Alice", age: 25 }; // 合并后的 User 接口包含了 name 和 age 属性
3.2 type
不能合并
type
不支持声明合并,如果多次定义同一个类型名会报错。
type UserType = {
name: string;
};
// 再次定义同名类型会报错
type UserType = {
age: number; // Error: Duplicate identifier 'UserType'.
};
区别:
-
interface
支持声明合并,允许多个同名的接口自动合并属性。 -
type
不支持重复声明。
4. 联合类型和交叉类型
4.1 type
支持联合类型和交叉类型
type
支持定义 联合类型 和 交叉类型,而 interface
不支持。
// 联合类型
type Status = "success" | "error" | "loading";
// 交叉类型
type Name = { name: string };
type Age = { age: number };
type Person = Name & Age;
const person: Person = { name: "Alice", age: 25 };
4.2 interface
不支持联合类型
interface
无法直接用于定义联合类型。
// 不支持
interface Status = "success" | "error" | "loading"; // Error
区别:
type
支持联合类型和交叉类型,因此在组合多种类型时更加灵活。interface
无法用于定义联合类型,但可以用于定义对象类型的扩展。
5. 类型别名
type
可以用来定义除对象之外的其他类型别名,例如基本类型、元组、联合类型等。
// 定义基本类型别名
type ID = number | string;
// 定义元组类型
type Point = [number, number];
const id: ID = 123;
const point: Point = [10, 20];
interface
则只能用于定义对象类型。
6. 实现(Implements)和继承(Extends)
6.1 interface
支持类实现
interface
可以用来约束类的结构。
interface User {
name: string;
age: number;
}
class Person implements User {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
}
6.2 type
也可以约束类
虽然通常 interface
用于类的约束,但 type
也可以达到类似的效果。
type UserType = {
name: string;
age: number;
};
class PersonType implements UserType {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
}
区别:
interface
在类的设计模式中更加常用,因为它允许声明合并并且有更强的类型扩展能力。type
也可以用于类的约束,但主要用于联合类型和其他复杂类型组合。
7. 互操作性
7.1 interface
可以与 type
混合使用
interface
和 type
在实际开发中可以互相组合使用。例如,一个 interface
可以扩展一个 type
,反之亦然。
type Name = { name: string };
interface User extends Name {
age: number;
}
const user: User = { name: "Alice", age: 25 };
7.2 type
也可以扩展 interface
interface User {
name: string;
age: number;
}
type Admin = User & {
role: string;
};
const admin: Admin = { name: "Bob", age: 35, role: "Admin" };
区别:
interface
可以扩展type
,type
也可以扩展interface
,它们可以相互组合使用。
8. 复杂类型的表达能力
8.1 type
的表达能力更强
因为 type
支持联合类型、交叉类型、基本类型别名等复杂类型的组合,因此在处理复杂类型表达时,type
更加灵活。
type ComplexType = string | number | { name: string };
const value1: ComplexType = "Hello"; // 正确
const value2: ComplexType = 123; // 正确
const value3: ComplexType = { name: "Alice" }; // 正确
8.2 interface
主要用于对象结构
interface
主要用于描述对象的结构,在联合类型和复杂组合类型场景下不如 type
灵活。
// interface 无法直接定义联合类型
// interface ComplexType = string | number | { name: string }; // Error
9. 使用场景总结
interface
的适用场景:- 定义对象类型,尤其是面向对象的设计模式。
- 类的约束,接口扩展和实现(implements)。
- 需要声明合并的场景(如第三方库中的类型定义)。
type
的适用场景:- 联合类型、交叉类型等复杂类型定义。
- 基本类型和元组类型别名。
- 需要表达多个类型组合时更灵活。
总结
特性 | interface | type |
---|---|---|
定义对象类型 | ✅ | ✅ |
定义基本类型别名 | ❌ | ✅ |
声明合并 | ✅ | ❌ |
扩展方式 | extends 继承 | & 交叉类型 |
支持联合类型 | ❌ | ✅ |
支持交叉类型 | ❌ | ✅ |
用于类的实现 | ✅ | ✅(但不常见) |
表达能力 | 适合对象结构定义 | 适合复杂类型组合 |
常用场景 | 面向对象设计,类与接口组合使用 | 联合类型、复杂类型定义,类型别名等 |
总体来说,interface
更适合用于面向对象编程,特别是在类的设计和继承中。type
更加灵活,适用于更复杂的类型组合和类型别名的场景。在大多数项目中,interface
和 type
是可以互补使用的。
最后分享两个我的两个开源项目,它们分别是:
这两个项目都会一直维护的,如果你想参与或者交流学习,可以加我微信 yunmz777 如果你也喜欢,欢迎 star 🚗🚗🚗