类型推断与类型守卫

推断让多数位置无需手写注解;类型守卫在分支中把联合类型缩窄到具体成员,是与 unknown接口与类型别名 的可辨识联合配合的核心技能。


推断(Inference)

  • 从初始值推断变量类型;any 渗透会拖累整条推断链。
  • 从返回值推断函数返回类型;递归与条件类型过深时可能「递归过深」报错(见 高级类型)。
  • 泛型多数从实参推断(见 泛型)。
  • 上下文类型:回调形参类型由左侧期望类型推断(如 Array.prototype.map)。

加宽(Widening)与 const

let x = 'a' 可能推断为 stringas constconst 绑定可保留字面量,便于构造精确联合。


typeof 窄化(值空间)

function pad(x: string | number) {
  if (typeof x === 'string') return x.padStart(2)
  return x.toFixed(2)
}

注意:typeof null === 'object' 的 JS 历史问题;联合含 null 时需额外判断。


instanceofin

  • instanceof:原型链检测。
  • 'field' in obj:属性存在性;结合接口与类型别名时,可辨识联合常用 kind / type 字段

可辨识联合(Discriminated union)

type Ok<T> = { tag: 'ok'; value: T }
type Err = { tag: 'err'; message: string }
type R<T> = Ok<T> | Err
 
function unwrap<T>(r: R<T>): T {
  if (r.tag === 'ok') return r.value
  throw new Error(r.message)
}

tag判别属性;配合 switch 易做穷尽检查(never 辅助)。


用户定义类型守卫:x is T

function isString(x: unknown): x is string {
  return typeof x === 'string'
}

返回 true 时,调用点对 x 窄化为 string


断言与非空断言

  • as:告诉编译器「相信我」;过度使用等于绕过检查。
  • ! 后缀:断言非 null/undefinedstrictNullChecks 下常见但应确信逻辑。

相关链接