如何创建TypeScript类'in'运算符的带键提示函数并解决类型警告
修复TypeScript中带键提示的
hasKey函数类型谓词警告 我尝试在TypeScript中创建一个功能类似in运算符且带有键提示的函数,但不知道如何正确编写类型谓词。返回类型Pick<T, K>出现警告,但代码实际运行正常。
相关代码:
const users = { "Alice": { "id": 1, "name": "Alice", "age": 30, "isActive": true }, "Bob": { "id": 2, "name": "Bob", "birthYear": 1985, "hasSubscription": false }, "Charlie": { "id": 3, "name": "Charlie", "isAdmin": false, "age": 34 }, "Diana": { "id": 4, "name": "Diana", "age": 28, "isVerified": true }, "Eve": { "id": 5, "name": "Eve", "dob": "1992-05-15", "isEmployee": true } } type AllKeys<T> = T extends unknown ? keyof T : never /** Pick<T, K> is warning*/ //@ts-ignore function hasKey<T extends object, K extends AllKeys<T>>(obj: T, key: K): obj is Pick<T, K> { return key in obj } const userKey = "Alice" as keyof typeof users const user = users[userKey] if ("hasSubscription" in user) { user.hasSubscription } if (hasKey(user, "isVerified")) { user.isVerified }
问题原因
Pick<T, K>的作用是从类型T中选取指定键K组成新类型,但我们的函数是要断言原对象本身包含键K,而非将对象类型缩小为仅含K键的新类型。这种类型不匹配导致了TypeScript警告。
解决方案
将类型谓词的返回类型修改为obj is Extract<T, Record<K, unknown>>,该类型会从联合类型T中筛选出包含键K的成员,和in运算符的类型缩小逻辑完全一致:
type AllKeys<T> = T extends unknown ? keyof T : never // 无警告的正确实现 function hasKey<T extends object, K extends AllKeys<T>>(obj: T, key: K): obj is Extract<T, Record<K, unknown>> { return key in obj }
效果说明
修改后:
- 调用
hasKey(user, "isVerified")时,TypeScript会正确将user的类型缩小为包含isVerified键的Diana对象类型 - 类型提示正常工作,同时不再有任何警告
- 完全复刻了原生
in运算符的类型缩小能力,还保留了键提示功能
内容的提问来源于stack exchange,提问作者JameyPlay
相关产品推荐
相关产品推荐

