TS 在遇到以下这些条件语句时,会在语句的块级作用域内「收紧」变量的类型,这种类型推断的行为称作类型守卫 (Type Guard)。

类型守卫可以帮助我们在块级作用域中获得更为精确的变量类型,从而减少不必要的类型断言

例如该代码,其声明了一个名为padLeft的函数,接收一个类型为 number 或 string 的 padding 形参与类型为 string 的 input 形参,并将 padding 和 input 的值拼接为一个字符串

function padLeft(padding: number | string, input: string) {
  return " ".repeat(padding) + input;
}

但 .repeat() 只适用于 number 类型,如果传入的 padding 本身为 string,就会抛出错误

Argument of type 'string | number' is not assignable to parameter of type 'number'.
  Type 'string' is not assignable to type 'number'.

我们没有显式地处理 padding 为 number 或 string 的情况,所以我们需要精确处理每一种可能

function padLeft(padding: number | string, input: string) {
  if (typeof padding === "number") {
    return " ".repeat(padding) + input;
  }
  return padding + input;
}

通过 if 分支,TypeScript 能够看见并将 typeof padding === “number” 理解为一个代码的特殊形式,这称为 类型守卫(type guard)