You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 09:10:56