为了能跨函数上下文进行类型收集,可以通过 is 关键词显式向 TypeScript 提供类型信息

假设有以下场景:

const foo = (value: string | number) => {
  if (typeof value === "string") {
    return value.length;
  }
  // typeof value === 'number'
  return value;
};

正常情况下,TS 并不会报错,因为有 if 语句显式处理了 value 类型为 string 的情况,分支结束后再查看 value 的类型,会只剩下 number

但是如果将判定 value 为 string 的这个条件抽离为一个函数,那 TS 会无法判定进入 if 分支的 value 是什么类型。即使根据函数返回结果,我们完全可以确定进入的一定是 string 类型

const isString = (value: uknown): boolean => typeof value === "string";

const foo = (value: string | number) => {
  if (isString(value)) {
    // 爆红,因为 TS 认为此时的 value 也可以是 number 类型
    return value.length;
  }
  return value;
};

此时可以通过 is 关键词来声明。如果 isString 函数结果返回为 true,那 is 关键字前这个参数的类型就会被解析为 is 关键字后声明的类型

const isString = (value: uknown): value is string => typeof value === "string";

const foo = (value: string | number) => {
  if (isString(value)) {
    // 不会爆红。因为 isString 函数的返回结果为 true,所以 value 的类型被标注为了 string
    return value.length;
  }
  return value;
};