正在TypeScript中为泛型函数创建自定义返回类型



我有以下通用函数:

function getFoodProperties<T, K extends keyof T>(foods: T[], keys: K[]): any[] { // <-- any needs to be typed according to generic types?
return foods.map((food) => {
let obj: any = {}; // <-- this any also needs typing - it should be the same type as the one above I think?
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 },
];
getFoodProperties(foods, ["name", "colour"]);

我想大部分都是打字的,但我在键入新对象形状的返回时遇到了问题。对象键是根据getFoodProperties第二个参数中的项目拾取的。到目前为止,它正在输出正确的数据,但它没有被键入。

似乎没有为let obj分配类型,它错误为:

Type 'K' cannot be used to index type '{}'

因此,我认为我需要创建一个用于函数返回值和foods映射中的内部对象的泛型类型,但我不确定如何处理它

您几乎已经拥有了它。您知道Pick助手类型吗?Pick<T, K>创建一个新的对象类型,其中键K是从类型T中"拾取"的。

在您的情况下,正确的返回类型应该是Pick<T, K>[],这似乎给出了您想要的推断:

function getFoodProperties<T, K extends keyof T>(foods: T[], keys: K[]): Pick<T, K>[] {
// ...
}
// This is now an array of objects with "name" and "colour" properties only.
const result = getFoodProperties(foods, ["name", "colour"]);
result.forEach(food => {
food.name;
food.colour;
food.weight; // Property 'weight' does not exist on type 'Pick<IFoods, "name" | "colour">'
})

对于内部变量obj的类型,我建议将其保留为any。您可以使用相同的类型Pick<T, K>,但在这种情况下,TypeScript将要求立即在对象中定义名称和颜色属性,您不能像现在这样将它们作为第二步指定。如果您绝对希望避免使用any,那么可以考虑在返回行上使用带有强制转换的Partial<Pick<T, K>>,将类型改回仅使用Pick<T, K>:

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

游乐场链接

最新更新