如何使用内置类型守卫将unknown/object类型收窄为指定对象类型?
问题解答
可以通过TypeScript内置类型守卫完成该场景的类型判别,不需要自定义类型守卫。
报错原因
原有代码报错是低版本TypeScript(4.9以下)的控制流分析对单行多条件组合的类型收窄支持不完善:当你先将unknown类型的x收窄为object类型后,单行条件内的'a' in x没有正确触发属性追加的类型收窄,导致无法直接访问x.a。
解决方案
方案1:拆分嵌套判断(兼容所有TS版本)
将单行条件拆分为嵌套的判断分支,即可触发内置类型守卫的正确收窄:
const x: unknown = {a: 1}; if (typeof x === 'object' && x !== null) { // 第一层收窄:x 为非空对象类型 if ('a' in x) { // 第二层收窄:x 包含属性a,类型被标记为 object & {a: unknown} if (typeof x.a === 'number') { // 第三层收窄:a属性为数字类型,x最终类型为 {a: number} console.log("x's type is a subtype of {a: number}"); } } }
方案2:升级TypeScript到4.9及以上版本
4.9版本优化了in操作符的类型收窄逻辑,原有单行写法可以直接正常运行,无需修改代码。
用到的内置类型守卫说明
本次实现完全依赖TypeScript原生内置的类型守卫能力,没有额外自定义逻辑:
typeof类型守卫:用于收窄原始类型,分别判断变量为对象类型、属性a为数字类型- 非空判断守卫:通过
x !== null排除空值场景,避免后续操作报错 in类型守卫:判断对象存在指定属性,同时自动为对象类型追加对应属性的类型定义
内容的提问来源于stack exchange,提问作者Carl Patenaude Poulin
相关产品推荐
相关产品推荐

