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

如何在TypeScript中实现具备类型安全的pluck函数?

嘿,我之前也折腾过这个类型安全的pick函数,咱们来搞定它~

你参考的那个类型签名方向是完全对的,可能是你在写函数体的时候没处理好类型断言,或者忽略了TS运行时和类型系统的差异。下面是可以直接用的完整实现:

完整的类型安全pick函数实现

function pick<T, K extends keyof T>(obj: T, ...keys: K[]): Pick<T, K> {
  // 初始化结果对象,用Pick<T, K>断言类型,告诉TS后续会填充正确属性
  const result = {} as Pick<T, K>;
  
  // 遍历传入的key,逐个从原对象提取属性
  keys.forEach(key => {
    result[key] = obj[key];
  });
  
  return result;
}

为什么这么写?

  • 类型约束:K extends keyof T确保你传入的所有keys都是原对象obj的有效属性名,编译时就会阻止你传入不存在的key(比如pick(obj, 'd')会直接报错),完美保证类型安全。
  • 返回值类型:用TS内置的Pick<T, K>工具类型,自动帮我们生成只包含指定属性的新类型,完全符合你想要的{a:1, b:2}对应的类型{a: number; b: number}。
  • 运行时处理:因为TS的类型信息在运行时会被擦除,所以我们需要手动遍历keys并复制属性,这里用类型断言as Pick<T, K>是因为初始空对象{}不满足返回值类型的结构,需要明确告诉TS我们后续会把它填充成符合要求的对象。

测试你的例子

const obj = {a:1, b: 2, c: 3};
const plucked = pick(obj, 'a', 'b'); 
// plucked的类型是{ a: number; b: number; },值是{ a: 1, b: 2 },完全符合预期!

兼容旧TS版本(如果需要)

如果你的TS版本低于2.1(Pick工具类型是2.1才加入的),可以手动实现Pick类型:

// 手动实现Pick工具类型
type Pick<T, K extends keyof T> = {
  [P in K]: T[P];
};

// 然后再写pick函数,和上面一样
function pick<T, K extends keyof T>(obj: T, ...keys: K[]): Pick<T, K> {
  const result = {} as Pick<T, K>;
  keys.forEach(key => {
    result[key] = obj[key];
  });
  return result;
}

这样应该就能解决你编译不通过的问题啦~

内容的提问来源于stack exchange,提问作者Ruan Mendes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:26:07