You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 00:22:44