类型推断与类型守卫
推断让多数位置无需手写注解;类型守卫在分支中把联合类型缩窄到具体成员,是与 unknown、接口与类型别名 的可辨识联合配合的核心技能。
推断(Inference)
- 从初始值推断变量类型;
any渗透会拖累整条推断链。 - 从返回值推断函数返回类型;递归与条件类型过深时可能「递归过深」报错(见 高级类型)。
- 泛型多数从实参推断(见 泛型)。
- 上下文类型:回调形参类型由左侧期望类型推断(如
Array.prototype.map)。
加宽(Widening)与 const
let x = 'a' 可能推断为 string;as const 或 const 绑定可保留字面量,便于构造精确联合。
typeof 窄化(值空间)
function pad(x: string | number) {
if (typeof x === 'string') return x.padStart(2)
return x.toFixed(2)
}注意:typeof null === 'object' 的 JS 历史问题;联合含 null 时需额外判断。
instanceof 与 in
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/undefined;strictNullChecks下常见但应确信逻辑。