跳到主要内容

TypeScript 可辨识联合

TypeScript的可辨识联合(Discriminated Unions)是一种强大的类型工具,它允许我们通过共享字段来区分联合类型中的不同成员。这种技术特别适用于处理具有相似结构但行为不同的对象类型。

什么是可辨识联合?

可辨识联合是一种特殊的联合类型,其中每个成员都有一个共同的字段(通常是一个字面量类型),用于区分不同的类型。这个共享字段被称为“判别式”或“标签”。通过检查这个字段的值,TypeScript可以推断出当前处理的是哪个具体的类型。

基本语法

假设我们有一个表示不同形状的联合类型,每个形状都有一个kind字段来标识其类型:

typescript
type Shape = Circle | Square;

interface Circle {
kind: "circle";
radius: number;
}

interface Square {
kind: "square";
sideLength: number;
}

在这个例子中,kind字段是一个字面量类型,用于区分CircleSquare

如何使用可辨识联合?

1. 定义联合类型

首先,我们需要定义一个联合类型,其中每个成员都有一个共同的字段(如kind):

typescript
type Shape = Circle | Square;

interface Circle {
kind: "circle";
radius: number;
}

interface Square {
kind: "square";
sideLength: number;
}

2. 使用类型守卫

通过检查kind字段的值,我们可以编写类型安全的代码:

typescript
function getArea(shape: Shape): number {
switch (shape.kind) {
case "circle":
return Math.PI * shape.radius ** 2;
case "square":
return shape.sideLength ** 2;
}
}

在这个例子中,TypeScript能够根据shape.kind的值推断出shape的具体类型,从而确保我们在计算面积时使用的是正确的属性。

实际应用场景

场景1:处理不同的事件类型

假设我们有一个事件系统,其中包含不同类型的事件(如点击事件、键盘事件等)。我们可以使用可辨识联合来处理这些事件:

typescript
type Event = ClickEvent | KeyPressEvent;

interface ClickEvent {
type: "click";
x: number;
y: number;
}

interface KeyPressEvent {
type: "keypress";
key: string;
}

function handleEvent(event: Event) {
switch (event.type) {
case "click":
console.log(`Clicked at (${event.x}, ${event.y})`);
break;
case "keypress":
console.log(`Key pressed: ${event.key}`);
break;
}
}

场景2:处理不同的API响应

在处理API响应时,我们可能会遇到不同的响应类型(如成功响应、错误响应)。使用可辨识联合可以确保我们正确处理每种响应:

typescript
type ApiResponse = SuccessResponse | ErrorResponse;

interface SuccessResponse {
status: "success";
data: any;
}

interface ErrorResponse {
status: "error";
error: string;
}

function handleResponse(response: ApiResponse) {
switch (response.status) {
case "success":
console.log("Data:", response.data);
break;
case "error":
console.error("Error:", response.error);
break;
}
}

总结

TypeScript的可辨识联合是一种强大的工具,它通过共享字段来区分联合类型中的不同成员,从而提升代码的类型安全性和可读性。通过定义联合类型和使用类型守卫,我们可以编写出更加健壮和易于维护的代码。

附加资源

练习

  1. 定义一个表示不同动物的联合类型,每个动物都有一个type字段来标识其类型(如DogCat)。编写一个函数,根据动物的类型输出不同的声音。

  2. 扩展上述事件系统的例子,添加一个新的事件类型(如MouseMoveEvent),并更新handleEvent函数以处理新的事件类型。

通过完成这些练习,你将更深入地理解TypeScript可辨识联合的用法和应用场景。