如何创建可判断泛型对象是否含指定key的TypeScript类型守卫函数
解决方案
你原有写法的问题在于类型守卫只收窄了key的类型,没有同步收窄对象本身的类型,当对象是联合类型时,TS无法自动过滤不包含目标key的类型分支。以下是符合需求的通用实现:
export function has<T extends object, K extends PropertyKey>( obj: T, property: K ): obj is T & Record<K, unknown> { // 若要完全和`key in obj`行为一致(包含原型链属性),替换为下面这行 // return property in obj return Object.prototype.hasOwnProperty.call(obj, property) }
效果验证
你的原有测试代码可以正常完成类型收窄:
interface Foo { bar: string } interface Fuzz { buzz: string } function doWork(thing: Foo | Fuzz) { if (has(thing, 'bar')) { alert(thing.bar) // 现在可以正确识别thing为Foo类型,bar属性存在 } }
实现说明
- 用两个泛型分别捕获对象类型
T和目标键的字面量类型K,PropertyKey是TS内置类型,包含所有合法的键类型:string | number | symbol - 类型守卫
obj is T & Record<K, unknown>会自动从联合类型T中过滤掉不包含键K的类型分支,同时保留原有属性的类型定义 - 如果你需要和
key in obj完全一致的行为(会遍历原型链查找属性),可以把判断逻辑换成return property in obj即可
内容的提问来源于stack exchange,提问作者jpschroeder
相关产品推荐
相关产品推荐

