TypeScript 联合类型
什么是联合类型?
在 TypeScript 中,联合类型(Union Types) 是一种允许变量或参数具有多种类型的机制。通过联合类型,你可以定义一个变量可以是多种类型中的一种。例如,一个变量可以是 string
或 number
,但不能是其他类型。
联合类型使用竖线符号 |
来分隔不同的类型。例如:
let value: string | number;
value = "Hello"; // 合法
value = 42; // 合法
value = true; // 错误:布尔类型不在联合类型中
联合类型的主要作用是增强代码的灵活性,同时保持类型安全性。它允许你在不牺牲类型检查的情况下处理多种类型的值。
联合类型的基本用法
1. 定义联合类型
联合类型的定义非常简单,只需在类型声明中使用 |
分隔多个类型即可。例如:
let id: string | number;
id = "abc123"; // 合法
id = 123; // 合法
id = true; // 错误:布尔类型不在联合类型中
2. 函数参数中的联合类型
联合类型常用于函数参数,允许函数接受多种类型的输入。例如:
function printId(id: string | number) {
console.log(`ID is: ${id}`);
}
printId("abc123"); // 输出: ID is: abc123
printId(123); // 输出: ID is: 123
3. 联合类型与类型推断
TypeScript 会根据上下文自动推断联合类型的实际类型。例如:
let value: string | number;
value = "Hello";
console.log(value.toUpperCase()); // 合法,因为 value 是 string 类型
value = 42;
console.log(value.toFixed(2)); // 合法,因为 value 是 number 类型
在使用联合类型时,TypeScript 会根据当前值的类型提供相应的类型提示和方法。
联合类型的类型守卫
由于联合类型的变量可能是多种类型之一,直接操作时可能会遇到类型不匹配的问题。为了解决这个问题,TypeScript 提供了类型守卫(Type Guards)。
1. 使用 typeof
进行类型守卫
typeof
是 JavaScript 中的运算符,可以用来检查变量的类型。在 TypeScript 中,它可以用于联合类型的类型守卫:
function printValue(value: string | number) {
if (typeof value === "string") {
console.log(`String value: ${value.toUpperCase()}`);
} else {
console.log(`Number value: ${value.toFixed(2)}`);
}
}
printValue("hello"); // 输出: String value: HELLO
printValue(3.14159); // 输出: Number value: 3.14
2. 使用 instanceof
进行类型守卫
如果联合类型中包含类或构造函数类型,可以使用 instanceof
进行类型守卫:
class Dog {
bark() {
console.log("Woof!");
}
}
class Cat {
meow() {
console.log("Meow!");
}
}
function makeSound(animal: Dog | Cat) {
if (animal instanceof Dog) {
animal.bark();
} else {
animal.meow();
}
}
makeSound(new Dog()); // 输出: Woof!
makeSound(new Cat()); // 输出: Meow!
联合类型的实际应用场景
1. 处理 API 响应
在实际开发中,API 响应的数据类型可能因情况而异。例如,一个 API 可能返回成功的数据或错误信息:
type ApiResponse = { status: "success"; data: any } | { status: "error"; message: string };
function handleResponse(response: ApiResponse) {
if (response.status === "success") {
console.log("Data:", response.data);
} else {
console.error("Error:", response.message);
}
}
handleResponse({ status: "success", data: { id: 1, name: "John" } });
handleResponse({ status: "error", message: "Invalid request" });
2. 处理用户输入
在处理用户输入时,输入可能是字符串或数字。使用联合类型可以确保代码的健壮性:
function processInput(input: string | number) {
if (typeof input === "string") {
console.log(`Input is a string: ${input.trim()}`);
} else {
console.log(`Input is a number: ${input.toFixed(2)}`);
}
}
processInput(" Hello "); // 输出: Input is a string: Hello
processInput(3.14159); // 输出: Input is a number: 3.14
总结
联合类型是 TypeScript 中非常强大的特性,它允许你定义变量或参数的多重类型,从而提升代码的灵活性和安全性。通过类型守卫,你可以确保在操作联合类型时不会出现类型错误。
在实际开发中,联合类型常用于处理 API 响应、用户输入等场景。掌握联合类型的使用,将使你的 TypeScript 代码更加健壮和可维护。
附加资源与练习
练习
- 定义一个联合类型
Result
,它可以是{ success: true; data: any }
或{ success: false; error: string }
,并编写一个函数处理该类型。 - 尝试使用联合类型和类型守卫处理一个包含多种类型的数组。