TypeScript如何用type predicate判断对象存在指定key并实现类型收窄
错误原因
TS 默认无法通过普通的属性存在性判断自动收窄联合类型的键类型,你自定义的objHasKey函数没有声明类型谓词,TS 无法从返回结果推断key的实际类型,因此访问obj1[key]、obj2[key]时会抛出索引不匹配的错误。
正确实现
首先把objHasKey改造为带类型谓词的类型守卫函数:
// 泛型T绑定为对象类型,返回值用key is keyof T声明类型谓词 function objHasKey<T extends object>(obj: T, key: PropertyKey): key is keyof T { return obj.hasOwnProperty(key) }
改造完成后,你的业务代码无需修改即可正常通过类型校验:
const obj1 = { foo: 123 } const obj2 = { bar: 456 } type ObjKey = keyof typeof obj1 | keyof typeof obj2 function getVal(key: ObjKey) { // 判断为true时,TS会自动把key的类型收窄为'foo',因此obj1[key]类型合法 return objHasKey(obj1, key) ? obj1[key] : obj2[key] }
补充说明
- 类型谓词
key is keyof T的作用就是告诉TS:当函数返回true时,入参key一定是入参obj的自有键,以此完成类型收窄 - 用
hasOwnProperty做判断可以避免原型链上的属性干扰,符合绝大多数业务场景的预期
内容的提问来源于stack exchange,提问作者Sean
相关产品推荐
相关产品推荐

