交叉类型(Intersection Types)和联合类型(Union Types)是 TypeScript 中用于创建复杂类型的两种重要工具。它们有助于更灵活地定义类型,但有着不同的语义和用途。
交叉类型(Intersection Types)
定义: 交叉类型 A & B 表示一个类型,它同时具有类型 A 和类型 B 的所有属性。
用途: 交叉类型用于合并多个类型的属性。它创建的是一个新类型,这个新类型要求同时满足所有合并的类型约束。
示例:
type A = { name: string };
type B = { age: number };
type Person = A & B;
const john: Person = {
name: "John",
age: 30
// 必须同时包含 name 和 age 属性
};在上面的例子中,Person 类型同时具备 A 和 B 类型的所有属性,因此 john 变量必须同时有 name 和 age 属性。
联合类型(Union Types)
定义: 联合类型 A | B 表示一个类型,它可以是 A 类型,也可以是 B 类型,但不同时具有这两种类型的所有属性。
用途: 联合类型用于创建能够持有多种不同类型中的一种的变量。这在函数参数、变量和返回值类型需要多态性时非常有用。
示例:
type A = { name: string };
type B = { age: number };
type Either = A | B;
const alice: Either = { name: "Alice" }; // 有效
const bob: Either = { age: 25 }; // 有效
const charlie: Either = { name: "Charlie", age: 40 }; // 也有效,因为它满足 A 和 B 的其中之一在上面的例子中,alice 和 bob 变量可以是 A 类型或 B 类型中的任意一种。charlie 变量同时具备 A 和 B 类型的属性,因此它满足 Either 类型的要求。
区别与使用场景
| 特点 | 交叉类型 | 联合类型 |
|---|---|---|
| 定义 | 同时具有所有类型的属性 | 具有多种类型中的一种 |
| 语法 | A & B | A | B |
| 示例 | { a: string } & { b: number } = { a: "hi", b: 10 } | { a: string } | { b: number } = { a: "hi" } or { b: 10 } |
| 使用场景 | 合并多个对象的属性 | 允许变量是多种类型之一 |
| 检查属性 | 同时具备所有交叉的属性 | 可以具有单独一种类型属性,但不能混合所有属性 |
实际应用
交叉类型的应用场景
-
增强类型: 你可以将多种类型的属性组合成一个更强大的类型。
type Drawable = { draw: () => void }; type Erasable = { erase: () => void }; type DrawingTool = Drawable & Erasable; const tool: DrawingTool = { draw: () => console.log("Drawing"), erase: () => console.log("Erasing") }; -
混合多个接口或类型:
interface Point { x: number; y: number; } interface Colored { color: string; } type ColoredPoint = Point & Colored; const coloredPoint: ColoredPoint = { x: 0, y: 0, color: "red" };
联合类型的应用场景
-
多态函数参数: 允许函数参数接受多种类型。
function printId(id: string | number) { console.log("Your ID is: " + id); } printId(101); // 有效 printId("202"); // 也有效 -
类型别名: 用于函数返回多种类型中的一种。
type Success = { status: "success"; data: unknown }; type Error = { status: "error"; message: string }; type Response = Success | Error; function handleResponse(response: Response) { if (response.status === "success") { console.log("Data: " + response.data); } else { console.log("Error: " + response.message); } }
总结来说,交叉类型用于创建一个包含所有类型属性的组合类型,而联合类型则用于定义一个可以是多种类型中的某一个的类型。根据具体应用需求选择适合的类型,以实现更强大的类型系统。