TypeScript 类型守卫完全指南

类型守卫把宽泛类型收窄为具体类型:typeof、instanceof、in、自定义谓词与可辨识联合。本文系统讲解全部守卫手段。

最佳实践
类型结构与组件组合插画

类型守卫 = 运行时检查 + 编译期收窄:typeof 管原始类型、instanceof 管类、in 管属性存在性、自定义谓词函数(x is T)管复杂结构、可辨识联合的判别字段管联合类型。守卫是 as 断言的安全替代。

内置守卫

function process(value: string | number | Date) {
  if (typeof value === 'string') return value.toUpperCase();
  if (typeof value === 'number') return value.toFixed(2);
  if (value instanceof Date) return value.toISOString();
}

typeof 收窄原始类型;instanceof 收窄类实例;in 检查属性:

if ('breed' in animal) { animal.breed; }   // Dog 分支

自定义类型谓词

function isUser(value: unknown): value is User {
  return (
    typeof value === 'object' && value !== null &&
    'id' in value && 'name' in value
  );
}

// 使用处自动收窄
if (isUser(data)) {
  data.name;   // User——运行时验证 + 编译期认可
}

value is User 是魔法签名:函数返回 true 时,TS 在调用处收窄类型。

可辨识联合(Discriminated Union)

type Result =
  | { ok: true; data: User }
  | { ok: false; error: string };

if (result.ok) {
  result.data;   // 自动收窄到成功分支
} else {
  result.error;  // 失败分支
}

共同的字面量判别字段(ok)让 switch/if 成为天然守卫——TS 中最优雅的建模模式之一。

空值守卫

// filter 收窄的经典技巧
const valid = list.filter((x): x is NonNullable<typeof x> => x != null);
// (现代 TS 对 filter(Boolean) 也有内置收窄)

常见问题(FAQ)

Q:类型谓词函数会撒谎吗?

会——实现写错(返回 true 但实际不符)类型系统信你。谓词函数的正确性靠测试保障,或用 Zod 等库生成。

Q:Array.isArray 为什么必要?

typeof [] 是 'object'——数组收窄必须用 Array.isArray(它有内置谓词签名)。

Q:asserts 谓词?

asserts value is T:函数不返回而是"断言通过或抛错"——输入校验函数的签名模式。


参考文档

本文依据公开文档整理,示例需按项目依赖版本验证;不将文档中的性能描述视为本项目实测结果。

延伸阅读

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台