TypeScript动态生成映射值对象时的类型错误问题
解决TypeScript动态生成对象时的方法类型不匹配问题
问题场景
需要基于只读对象动态生成结构完全一致的新对象:新对象的每个键对应的值是包含exampleMethod的对象,该方法返回原对象对应键的具体值。使用reduce实现时出现类型不匹配错误。
原代码
const obj = { a: "valueA", b: "valueB" } as const; const objKeys = Object.keys(obj) as (keyof typeof obj)[]; const example = objKeys.reduce( (acc, v) => { acc[v] = { exampleMethod() { return obj[v]; }, }; return acc; }, {} as { -readonly [K in keyof typeof obj]: { exampleMethod(): (typeof obj)[K] }; }, );
错误信息
Type '() => "valueA" | "valueB"' is not assignable to type '(() => "valueA") & (() => "valueB")'. Type '() => "valueA" | "valueB"' is not assignable to type '() => "valueA"'. Type '"valueA" | "valueB"' is not assignable to type '"valueA"'. Type '"valueB"' is not assignable to type '"valueA"'.
问题原因
循环中变量v的类型是联合类型"a" | "b",TypeScript无法在reduce回调中自动将其细化为单个具体键,导致obj[v]被推断为联合值类型"valueA" | "valueB",但目标类型要求每个exampleMethod返回对应键的具体值类型,二者无法匹配。
解决方案
方案一:使用泛型函数细化类型
通过泛型函数处理每个键,让TypeScript准确推断单个键对应的具体类型:
const obj = { a: "valueA", b: "valueB" } as const; // 定义目标对象的类型 type ExampleType = { [K in keyof typeof obj]: { exampleMethod(): (typeof obj)[K]; }; }; const example = {} as ExampleType; // 泛型函数确保每个键的类型被正确识别 function setProp<K extends keyof typeof obj>(key: K) { example[key] = { exampleMethod() { return obj[key]; }, }; } // 遍历键完成赋值 (Object.keys(obj) as (keyof typeof obj)[]).forEach(setProp);
方案二:reduce中添加类型断言
如果坚持使用reduce,可以通过类型断言明确当前键的返回值类型:
const obj = { a: "valueA", b: "valueB" } as const; const objKeys = Object.keys(obj) as (keyof typeof obj)[]; type ExampleType = { -readonly [K in keyof typeof obj]: { exampleMethod(): (typeof obj)[K] }; }; const example = objKeys.reduce( (acc, v) => { acc[v] = { exampleMethod() { // 断言返回值为当前键对应的具体类型 return obj[v] as (typeof obj)[typeof v]; }, } as ExampleType[typeof v]; return acc; }, {} as ExampleType );
最终效果
生成的对象类型完全符合预期:
example.a.exampleMethod(); // 返回类型为 "valueA" example.b.exampleMethod(); // 返回类型为 "valueB"
内容的提问来源于stack exchange,提问作者Shmookoff
相关产品推荐
相关产品推荐

