目 录CONTENT

文章目录

TS(十二) 联合类型和交叉类型

Typescript(十二) 联合类型和交叉类型

TypeScript 联合类型(Union)和交叉类型(Intersection)是处理复杂类型的核心工具。

联合类型

值可以是多种类型中的 一种

let value: string | number;
value = "hello"; // ✅
value = 123; // ✅
value = true; // ❌ 报错

实际使用场景

函数参数多类型

function formatInput(input: string | number | Date): string {
  if (typeof input === "string") {
    return input.trim();
  }
  if (typeof input === "number") {
    return input.toFixed(2);
  }
  return input.toISOString();
}

可空类型

function findUser(id: number): User | undefined {
  // 找到返回 User,找不到返回 undefined
}

const user = findUser(1);
if (user) {
  user.name; // ✅ 安全访问
}

字面量联合(枚举替代)

type Status = "pending" | "success" | "error";
type Direction = "up" | "down" | "left" | "right";

function setStatus(status: Status) {
  // 只能传入这三个值
}

可辨识联合

type Shape =
  | { kind: "circle"; radius: number }
  | { kind: "square"; side: number }
  | { kind: "triangle"; base: number; height: number };

function getArea(shape: Shape): number {
  switch (shape.kind) {
    case "circle":
      return Math.PI * shape.radius ** 2;
    case "square":
      return shape.side ** 2;
    case "triangle":
      return (shape.base * shape.height) / 2;
  }
}

交叉类型

将多个类型 合并 为一个,包含所有类型的属性

简单示例

type A = { name: string };
type B = { age: number };

type Person = A & B; // { name: string; age: number }

const p: Person = { name: "张三", age: 25 };

实际使用场景

混入mixin模式

interface Loggable {
  log(msg: string): void;
}

interface Serializable {
  serialize(): string;
}

// 同时具有日志和序列化能力
class User implements Loggable & Serializable {
  name = "张三";

  log(msg: string) {
    console.log(msg);
  }

  serialize() {
    return JSON.stringify(this);
  }
}

扩展已有类型

interface BaseConfig {
  timeout: number;
  retries: number;
}

interface WithCache {
  cache: boolean;
  ttl: number;
}

// 组合配置
type FullConfig = BaseConfig & WithCache;

const config: FullConfig = {
  timeout: 5000,
  retries: 3,
  cache: true,
  ttl: 60000,
};

给函数参数添加约束

function merge<T extends object, U extends object>(a: T, b: U): T & U {
  return { ...a, ...b };
}

const result = merge({ name: "张三" }, { age: 25 });
// result: { name: string } & { age: number }

对比

联合 交叉 &
含义 或(多选一) 与(全都要)
属性 只能访问共有属性 可以访问所有属性
用途 参数多类型、状态枚举 类型组合、能力叠加
图示 并集的每个分支 交集的叠加

举例

// 联合:只能访问共有属性
type A = { name: string; a: number };
type B = { name: string; b: number };
type Union = A | B;

function test(u: Union) {
  u.name; // ✅ 共有属性
  u.a; // ❌ 报错,可能是 B
  u.b; // ❌ 报错,可能是 A
}

// 交叉:可以访问所有属性
type Intersection = A & B; // { name: string; a: number; b: number }

function test2(i: Intersection) {
  i.name; // ✅
  i.a; // ✅
  i.b; // ✅
}
0

评论区