不止一叶代码屋 个人技术博客 · 代码与生活的记录

前端开发

TypeScript 类型收窄:那些让类型「活起来」的写法

什么叫收窄

一个变量声明成联合类型后,TypeScript 会随着你写的判断,逐步缩小它的可能类型。

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

function handle(r: Result) {
  if (r.ok) {
    r.data;   // 这里 TS 知道是成功分支
  } else {
    r.error;  // 这里是失败分支
  }
}

这个 ok: true / ok: false 就叫可辨识联合,是最推荐的做法。

常见收窄手段

手段 例子
typeof typeof x === 'string'
instanceof x instanceof Date
in 'name' in obj
相等判断 x === 'success'
自定义守卫 function isUser(v: unknown): v is User

自定义类型守卫

当内置手段不够用时:

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

注意返回类型写的是 value is User,不是 boolean。写错这点守卫就完全失效。

踩过的坑

坑一:解构后丢失收窄

function f(r: Result) {
  const { ok } = r;
  if (ok) {
    r.data;  // 报错,收窄没跟着走
  }
}

对策:判断用原始变量,别解构。

坑二:闭包里失效

因为在回调执行时,外部变量可能已经变了。对策是把收窄后的值赋给新的 const。

小结

类型收窄是 TS 里投入产出比最高的知识之一。学明白之后,你会开始依赖类型检查,而不是绕过它。

订阅 RSS

← 返回首页