typescript类型守卫通过运行时判断实现联合类型收窄:typeof用于基础类型(需严格相等和小写字面量),instanceof用于类实例(注意iframe兼容性),in操作符用于对象结构判断;需分层组合、顺序合理且覆盖全面。

TypeScript 用类型守卫在运行时判断值的实际类型,让编译器在对应分支里自动把联合类型收窄成具体子类型,从而安全访问专属属性和方法。关键不在“写对语法”,而在于让判断逻辑清晰、可推导、覆盖全面。
用 typeof 守卫识别基础类型
适合 string | number | boolean 等原始类型。必须用严格相等(===)和小写字符串字面量,比如 typeof x === "string";写成 == 或 "String" 都不会触发收窄。
- null 是个特例:typeof null 返回 "object",所以 typeof x === "object" 不能代表 x 是对象——得加 && x !== null 才可靠
- 常见组合如 typeof v === "string" || typeof v === "number" 不会收窄,TypeScript 只认单一分支内的明确判断
- 示例:处理 string | number 时,if 分支内可直接调用 .trim() 或 .toFixed(2),无需断言
用 instanceof 守卫确认类实例
适用于自定义类、Date、Error、RegExp 等有原型链的对象。它依赖构造函数,运行时有效,且支持继承关系。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- Dog extends Animal 时,obj instanceof Dog 收窄为 Dog 类型,obj instanceof Animal 则收窄为 Animal 类型
- 跨 iframe 场景下,Array、Promise 等内置构造器的 instanceof 可能失效,优先用 Array.isArray()、Promise.resolve() 等更健壮的方法
- 注意:instanceof 对普通对象字面量({})或接口类型无效,它们没有构造函数
用 in 操作符检查对象结构
当联合类型由多个形状不同的对象组成(比如 { kind: "circle"; radius: number } | { kind: "square"; side: number }),in 是最自然的选择。
- "radius" in shape 成立,则 TypeScript 推断该分支中 shape 至少包含 radius 属性(即使 radius 是可选的)
- 配合字面量类型(如 kind: "circle")使用效果更好,比如 shape.kind === "circle" + "radius" in shape 能双重锁定类型
- 不依赖类或构造函数,纯靠属性存在性,适合接口、type 别名定义的联合对象
组合判断要讲顺序和完整性
真实数据往往混合基础类型、类实例、对象结构,单靠一种守卫不够。TypeScript 按 if-else 链逐级排除,顺序直接影响收窄结果。
- 推荐分层:先用 typeof 排除所有原始类型,再用 instanceof 或 in 处理剩余对象分支
- 避免漏判:如果联合类型是 A | B | C,三个分支必须穷尽所有可能,否则 else 分支里类型仍是未收窄的剩余联合类型
- 反例:把 instanceof Error 放在 typeof x === "string" 前面,即便 x 是字符串,编译器也无法据此排除 string 类型——它只看控制流是否实际进入该分支
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










