TypeScript:如何从对象数组的属性值构建泛型对象类型?
实现基于数组元素属性值的泛型Response类型
这个需求完全可以实现,核心是通过泛型捕获数组元素的valueIWant字面量类型,再用映射类型生成目标对象。以下是具体实现:
泛型类型定义
// 泛型类型:接收包含valueIWant属性的对象数组类型,生成对应键的对象 type ResponseFromObjects<T extends { valueIWant: string }[]> = { [K in T[number]['valueIWant']]: string; };
使用示例
要让TypeScript保留valueIWant的具体字面量值,需要用as const断言数组,避免被推断为宽泛的string类型:
// 用as const断言,让TypeScript识别具体的字面量值 const input = [ { valueIWant: 'makeMeAKey', foo: 'bar' }, { valueIWant: 'alsoMakeMeAKey', foo: 'bar' } ] as const; // 生成目标类型 type TargetResponse = ResponseFromObjects<typeof input>; // TargetResponse的类型为:{ makeMeAKey: string; alsoMakeMeAKey: string; }
结合函数自动推导类型
如果要在函数中自动处理类型,可以用readonly元组约束来捕获数组的字面量类型:
function buildResponse<T extends { valueIWant: string }[]>(arr: readonly [...T]) { return arr.reduce((res, item) => { res[item.valueIWant] = ''; // 这里替换为实际的赋值逻辑 return res; }, {} as ResponseFromObjects<T>); } // 调用时传入带const断言的数组,自动推导返回类型 const response = buildResponse([ { valueIWant: 'makeMeAKey', foo: 'bar' }, { valueIWant: 'alsoMakeMeAKey', foo: 'bar' } ] as const); // response的类型自动为:{ makeMeAKey: string; alsoMakeMeAKey: string; }
关键说明
- 必须使用
as const或readonly元组约束,否则TypeScript会将valueIWant推断为string,生成的类型会变成{ [x: string]: string },无法得到具体的键名。 - 泛型
T约束为包含valueIWant: string的对象数组,确保传入的类型符合要求,同时能正确提取键值类型。
内容的提问来源于stack exchange,提问作者Markos Sankey
相关产品推荐
相关产品推荐

