如何在TypeScript中从对象数组生成对应类型的对象?
解决TypeScript动态构建对象的类型推断问题
要让createObject函数能根据传入的props数组推断出正确的返回类型,需要调整泛型定义和返回类型的映射逻辑,具体修改如下:
修改后的函数实现
function createObject<T extends { propName: string; propValue: unknown }>( propertiesObject: readonly T[] ): { [K in T['propName']]: Extract<T, { propName: K }>['propValue'] } { const obj = {} as { [K in T['propName']]: Extract<T, { propName: K }>['propValue'] }; for (const { propName, propValue } of propertiesObject) { obj[propName as T['propName']] = propValue as any; } return obj; }
关键修改点说明
- 泛型约束调整:将泛型参数
T约束为单个props元素的类型(而非数组类型),参数接收readonly T[],让TypeScript能捕获每个元素中propName的字面量类型和propValue的具体类型。 - 返回类型映射:使用TypeScript的映射类型和
Extract工具类型,遍历T['propName']的所有字面量键,为每个键匹配对应的propValue类型:K in T['propName']:遍历所有传入的propName字面量作为对象的键Extract<T, { propName: K }>['propValue']:提取出对应propName为K的元素的propValue类型
- 类型断言:循环赋值时使用类型断言,因为TypeScript无法在循环中自动推断每个键对应的具体类型,这是安全的断言——我们已经通过泛型约束保证了类型的正确性。
测试验证
使用你提供的props数组测试,类型推断完全符合预期:
const props1 = [ { propName: 'id', propValue: 1 }, { propName: 'name', propValue: 'John' }, { propName: 'age', propValue: 30 } ] as const; // 用as const强制TypeScript保留字面量类型 const obj1 = createObject(props1); // 类型为 { id: number; name: string; age: number } const props2 = [ { propName: 'id', propValue: 2 }, { propName: 'role', propValue: 'admin' } ] as const; const obj2 = createObject(props2); // 类型为 { id: number; role: string }
注意:如果props数组是动态创建的,必须用as const强制TypeScript保留每个元素的字面量类型,否则propName会被推断为通用string类型,导致返回类型退化为{ [key: string]: unknown }。
内容的提问来源于stack exchange,提问作者Zuhair Taha
相关产品推荐
相关产品推荐

