跳到主要内容

TypeScript 交叉类型

什么是交叉类型?

在 TypeScript 中,交叉类型(Intersection Types) 是一种将多个类型合并为一个新类型的方式。通过使用 & 操作符,可以将多个类型的属性和方法组合在一起,形成一个新的类型。这个新类型包含了所有被组合类型的特性。

简单来说,交叉类型可以理解为“类型合并”,它允许你将多个类型的特性“叠加”在一起,从而创建一个更复杂的类型。

基本语法

交叉类型的基本语法如下:

typescript
type CombinedType = TypeA & TypeB;

这里的 TypeATypeB 可以是任意类型,CombinedType 将包含 TypeATypeB 的所有属性和方法。

示例 1:合并对象类型

假设我们有两个对象类型 PersonEmployee,我们可以通过交叉类型将它们合并为一个新的类型 PersonEmployee

typescript
type Person = {
name: string;
age: number;
};

type Employee = {
employeeId: number;
department: string;
};

type PersonEmployee = Person & Employee;

const employee: PersonEmployee = {
name: "Alice",
age: 30,
employeeId: 12345,
department: "Engineering",
};

在这个例子中,PersonEmployee 类型包含了 PersonEmployee 的所有属性。因此,employee 对象必须同时满足 PersonEmployee 的类型要求。

示例 2:合并函数类型

交叉类型不仅可以用于对象类型,还可以用于函数类型。假设我们有两个函数类型 LoggableSerializable,我们可以将它们合并为一个新的函数类型:

typescript
type Loggable = {
log: (message: string) => void;
};

type Serializable = {
serialize: () => string;
};

type LoggableAndSerializable = Loggable & Serializable;

const logger: LoggableAndSerializable = {
log: (message) => console.log(message),
serialize: () => JSON.stringify(logger),
};

在这个例子中,LoggableAndSerializable 类型包含了 LoggableSerializable 的所有方法。因此,logger 对象必须同时实现 logserialize 方法。

交叉类型的实际应用场景

场景 1:组合多个接口

在实际开发中,我们经常需要将多个接口组合在一起,以创建一个更复杂的类型。例如,假设我们有一个 User 接口和一个 Admin 接口,我们可以通过交叉类型将它们组合在一起:

typescript
interface User {
id: number;
name: string;
}

interface Admin {
permissions: string[];
}

type AdminUser = User & Admin;

const adminUser: AdminUser = {
id: 1,
name: "Bob",
permissions: ["read", "write", "delete"],
};

在这个例子中,AdminUser 类型包含了 UserAdmin 的所有属性。因此,adminUser 对象必须同时满足 UserAdmin 的类型要求。

场景 2:扩展第三方库类型

在使用第三方库时,我们可能需要扩展库提供的类型。例如,假设我们使用了一个库,它提供了一个 BaseComponent 类型,我们可以通过交叉类型来扩展这个类型:

typescript
type BaseComponent = {
render: () => void;
};

type WithLogging = {
log: (message: string) => void;
};

type LoggableComponent = BaseComponent & WithLogging;

const component: LoggableComponent = {
render: () => console.log("Rendering..."),
log: (message) => console.log(message),
};

在这个例子中,LoggableComponent 类型包含了 BaseComponentWithLogging 的所有方法。因此,component 对象必须同时实现 renderlog 方法。

交叉类型与联合类型的区别

备注

交叉类型联合类型 是 TypeScript 中两种不同的类型组合方式。交叉类型是将多个类型合并为一个新类型,而联合类型是表示一个值可以是多个类型中的任意一种。

例如:

typescript
type A = { a: string };
type B = { b: number };

type Intersection = A & B; // 交叉类型
type Union = A | B; // 联合类型
  • Intersection 类型的值必须同时满足 AB 的类型要求。
  • Union 类型的值可以是 AB 中的任意一种。

总结

交叉类型是 TypeScript 中一种强大的工具,它允许我们将多个类型合并为一个新类型。通过交叉类型,我们可以创建更复杂的类型,并在实际开发中灵活地组合和扩展类型。

附加资源

练习

  1. 创建一个 Vehicle 类型和一个 Drivable 类型,然后使用交叉类型将它们合并为一个 Car 类型。
  2. 尝试将一个函数类型和一个对象类型合并为一个新的类型,并实现该类型的对象。

通过练习,你将更好地理解交叉类型的使用场景和优势。