如何定义接收Record、返回同属性值类型转换后的Record的返回类型
TypeScript 对象属性类型精准转换实现方案
你当前的代码因为使用Record类型,会将所有属性值合并为联合类型,无法做到每个属性对应精准的转换结果。要实现每个属性类型的精准映射,完全可以通过TypeScript的映射类型(Mapped Types)来实现。
原问题代码回顾
type InputValue = number | boolean; type TransformValue<IV extends InputValue> = IV extends number ? "num" : "bool"; const transformObject = < Input extends Record<string, InputValue>, Key extends keyof Input, >( input: Input, ): Record<Key, TransformValue<Input[Key]>> => { // 原代码存在变量未定义、缺少return关键字的问题 /* ... */ }
需求:当输入如下对象时
const inputObject = { keyA: 123, keyB: true };
希望返回类型为:
{ keyA: "num"; keyB: "bool"; }
而非Record<"keyA" | "keyB", "num" | "bool">这种模糊的联合类型。
解决方案:使用映射类型逐个处理属性
将返回类型从Record改为映射类型,遍历输入对象的每个键,单独转换对应的值类型:
type InputValue = number | boolean; type TransformValue<IV extends InputValue> = IV extends number ? "num" : "bool"; // 定义精准转换后的对象类型 type TransformedObject<Input extends Record<string, InputValue>> = { [Key in keyof Input]: TransformValue<Input[Key]>; }; const transformObject = <Input extends Record<string, InputValue>>( input: Input ): TransformedObject<Input> => { // 函数实现示例 const result: Record<string, "num" | "bool"> = {}; for (const key in input) { if (typeof input[key] === "number") { result[key] = "num"; } else { result[key] = "bool"; } } return result as TransformedObject<Input>; };
验证效果
当你传入目标对象时,TypeScript会自动推导精准的返回类型:
const inputObject = { keyA: 123, keyB: true }; const output = transformObject(inputObject); // output的类型自动推导为:{ keyA: "num"; keyB: "bool"; }
原理说明
映射类型[Key in keyof Input]会遍历输入对象的每一个键Key,对每个Input[Key]单独应用TransformValue类型转换,从而保证每个属性的类型都是精准匹配的,不会合并为联合类型。
内容的提问来源于stack exchange,提问作者Vincent
相关产品推荐
相关产品推荐

