TypeScript 联合类型、收窄与类型守卫

解释联合类型如何表达多种可能,以及控制流和类型守卫如何在使用前缩小类型范围。

#type / concept #status / evergreen #tech / dev #resource / typescript

[!info] related notes

TypeScript 联合类型、收窄与类型守卫

一句话定义

联合类型表示一个值可能属于多个成员;收窄利用运行时检查和控制流,证明当前分支中只剩更具体的成员。

function messageOf(error: unknown): string {
  if (error instanceof Error) {
    return error.message;
  }
  return String(error);
}

内置收窄方式

  • typeof value === 'string'
  • value instanceof Error
  • 'field' in value
  • value !== null
  • 等值比较
  • 数组和库提供的判定函数,如 Array.isArray

收窄必须对应真实的运行时证据。as SomeType 不做检查,因此不是类型守卫。

自定义类型谓词

function isRecord(value: unknown): value is Record<string, unknown> {
  return typeof value === 'object' && value !== null && !Array.isArray(value);
}

谓词中的实现必须真的足以证明返回类型。只返回 true 或只检查一个无关字段,会把错误转移到运行时。

控制流分析

提前返回能让后续代码自然收窄:

function requireRunId(value: string | undefined): string {
  if (!value) throw new Error('run id is required');
  return value;
}

常见误解

  • 真值判断会同时排除 ''0false,不一定等价于判空。
  • in 只能证明属性存在,不能证明属性值的完整结构。
  • 类型守卫验证多少,返回类型就只能承诺多少。
创建于 2026/7/29 更新于 2026/7/29