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

如何实现类Pick泛型的取值函数?解决TypeScript类型报错

问题分析与解决方案

为什么会报错?

  1. 动态键的类型推断限制:当你用动态变量key作为对象字面量的键时,TypeScript会保守地将该对象的索引推断为string类型(JavaScript中对象键最终都会转为字符串或Symbol,TS对动态键的字面量做了宽泛处理),但你的返回类型是精确的Pick<T, K>(或等价映射类型),两者类型不匹配,因此触发报错。
  2. 返回类型的约束冲突:你定义的返回类型Pick<T, K>要求必须包含K对应的属性,但当key不存在于obj时,你返回了空对象{},这并不满足Pick<T, K>的类型约束,这也是类型不兼容的核心原因之一。

无需类型断言的实现方式

方案1:调整返回类型为可选属性映射

将返回类型改为包含可选属性的映射类型,让空对象{}和包含目标键的对象都能匹配类型约束,TS会自动通过类型检查:

function pick<T extends {}, K extends keyof T>(obj: T, key: K): { [P in K]?: T[P] } {
    return key in obj ? { [key]: obj[key] } : {};
}

这个方案完全不需要类型断言,同时符合你“存在则返回对应属性对象,不存在则返回空对象”的需求。

方案2:利用Object.fromEntries的类型推断

如果你希望返回类型严格区分Pick<T, K>和{},可以使用Object.fromEntries来创建对象,它能更精准地推断键的类型:

function pick<T extends {}, K extends keyof T>(obj: T, key: K): Pick<T, K> | {} {
    if (!(key in obj)) {
        return {};
    }
    return Object.fromEntries([[key, obj[key]]] as const) as Pick<T, K>;
}

这里的as const是为了让TS将数组元素推断为字面量类型,从而让fromEntries能正确生成Pick<T, K>类型的对象,仅在最后一步需要一次轻量的类型断言(相比直接断言整个对象更安全)。

内容的提问来源于stack exchange,提问作者Levi Haskell

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 06:10:11