Z
ZHANK
类型系统

联合与交叉类型

掌握 | 联合类型和 & 交叉类型的使用场景

联合与交叉类型

联合类型(|)和交叉类型(&)是 TypeScript 类型组合的核心工具。

学完本章你将: 掌握 |& 的使用场景与区别。


联合类型 (Union)

typescript
// 值可以是多种类型之一
type ID = string | number;

function printId(id: ID): void {
    console.log(`ID: ${id}`);
}
printId(101);    // ✅
printId("abc");  // ✅

// 联合类型在使用前需要收窄
function getLength(value: string | string[]): number {
    // 类型收窄
    if (Array.isArray(value)) {
        return value.length; // string[]
    }
    return value.length; // string
}

联合类型实战

typescript
// 状态机
type Status = "idle" | "loading" | "success" | "error";

function render(status: Status): string {
    switch (status) {
        case "idle": return "等待中…";
        case "loading": return "加载中…";
        case "success": return "加载成功!";
        case "error": return "加载失败";
    }
}

// API 响应类型
type ApiResponse<T> = 
    | { status: "ok"; data: T }
    | { status: "error"; message: string };

function handle(response: ApiResponse<number>): void {
    if (response.status === "ok") {
        console.log(response.data.toFixed(2));
    } else {
        console.error(response.message);
    }
}

交叉类型 (Intersection)

typescript
// 合并多个类型
type Name = { name: string };
type Age = { age: number };
type Person = Name & Age & { email: string };

const alice: Person = {
    name: "Alice",
    age: 25,
    email: "alice@example.com",
};

// 组合接口
interface Loggable { log(): void; }
interface Serializable { serialize(): string; }

type LoggableSerializable = Loggable & Serializable;

const obj: LoggableSerializable = {
    log() { console.log("logged"); },
    serialize() { return JSON.stringify(this); },
};

联合 vs 交叉

typescript
// 联合:满足其中一个
type A = { a: string };
type B = { b: number };
type Union = A | B;  // {a:string} 或 {b:number}

// 交叉:同时满足
type Intersection = A & B;  // {a:string; b:number}

// 实际对比
const u1: Union = { a: "hello" };         // ✅
const u2: Union = { b: 42 };              // ✅
const u3: Union = { a: "hi", b: 10 };     // ✅

const i: Intersection = { a: "hi", b: 10 }; // ✅
// const i2: Intersection = { a: "hi" };    // ❌ 缺少 b