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

TypeScript泛型函数自定义返回类型的实现疑问

解决TypeScript泛型函数提取对象属性的类型化问题

你的问题核心是要给getFoodProperties函数的返回值和内部对象obj指定正确的泛型类型,替代any来实现类型安全。可以直接利用TypeScript内置的Pick工具类型来解决这个问题,它专门用来从一个类型中选取指定键对应的属性集合。

改造后的完整代码

// 补充定义IFoods类型
interface IFoods {
  name: string;
  colour: string;
  weight: number;
}

function getFoodProperties<T, K extends keyof T>(foods: T[], keys: K[]): Pick<T, K>[] {
  return foods.map((food) => {
    // 用Pick<T, K>断言空对象,告诉TS这个对象最终会包含指定属性
    let obj = {} as Pick<T, K>;
    keys.forEach((key) => {
      obj[key] = food[key];
    });
    return obj;
  });
}

const foods: IFoods[] = [
  { name: "Beef", colour: "Red", weight: 8 },
  { name: "Chips", colour: "Yellow", weight: 1 },
  { name: "Lettuce", colour: "Green", weight: 9 },
];

// 返回值类型会被正确推导为Pick<IFoods, "name" | "colour">[],即{name: string; colour: string}[]
const result = getFoodProperties(foods, ["name", "colour"]);

关键改动说明

  • 返回值类型替换:把any[]改成Pick<T, K>[],Pick<T, K>表示从类型T中选取所有K包含的键对应的属性,组成新的类型,完全匹配提取指定属性的逻辑。
  • 内部obj类型处理:将obj的类型从any改为Pick<T, K>,但因为初始是空对象{},TypeScript无法自动推导它会包含K对应的属性,所以用as Pick<T, K>做类型断言,避免Type 'K' cannot be used to index type '{}'的报错。
  • 类型推导验证:调用函数时,传入["name", "colour"],TypeScript会自动将K推导为"name" | "colour",返回的result类型会被准确推断为包含name和colour属性的对象数组,后续使用时能获得完整的类型提示和校验。

可选优化:用reduce替代forEach

如果不想用类型断言,也可以用reduce构建对象,让TypeScript自动推导类型:

function getFoodProperties<T, K extends keyof T>(foods: T[], keys: K[]): Pick<T, K>[] {
  return foods.map((food) => {
    return keys.reduce((acc, key) => {
      acc[key] = food[key];
      return acc;
    }, {} as Pick<T, K>);
  });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 04:27:14