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

TypeScript 4.9中枚举键泛型函数集合映射报错问题咨询

TypeScript 4.9中枚举映射泛型函数集合的类型错误原因解析

以下代码在TypeScript 4.8中可正常运行,目标是创建以MyEnum枚举值作为键的映射,每个键对应一个依赖枚举值的泛型函数集合:

enum MyEnum {
  A = 'my-a',
  B = 'my-b',
}

type MyEnumToObjectMap = {
  [MyEnum.A]: {
    a: string;
  };
  [MyEnum.B]: {
    b: string;
  };
};

type MyGenericFunction<T extends MyEnum> = (data: MyEnumToObjectMap[T])=>void

type Functions = {
  [key in MyEnum]: Set<MyGenericFunction<key>>;
};

// Build the map
const map = {} as Functions;
for (const value of Object.values(MyEnum)) {
  map[value] = new Set<MyGenericFunction<typeof value>>();
}
console.log(map);

但在TypeScript 4.9中运行时会出现如下类型错误:

S2322: Type 'Set' is not assignable to type 'Set<MyGenericFunction<MyEnum.A>> & Set<MyGenericFunction<MyEnum.B>>'.
Types of property 'add' are incompatible.
Type '(value: MyGenericFunction) => Set' is not assignable to type '((value: MyGenericFunction<MyEnum.A>) => Set<MyGenericFunction<MyEnum.A>> & Set<MyGenericFunction<MyEnum.B>>) & ((value: MyGenericFunction<...>) => Set<...> & Set<...>)'.
Type '(value: MyGenericFunction) => Set' is not assignable to type '(value: MyGenericFunction<MyEnum.A>) => Set<MyGenericFunction<MyEnum.A>> & Set<MyGenericFunction<MyEnum.B>>'.
Types of parameters 'value' and 'value' are incompatible.
Types of parameters 'data' and 'data' are incompatible.
Type '{ a: string; } | { b: string; }' is not assignable to type '{ a: string; }'.
Property 'a' is missing in type '{ b: string; }' but required in type '{ a: string; }'.

错误原因

核心原因是TypeScript 4.9对循环中枚举值的类型推断逻辑进行了收紧:

  • 在TypeScript 4.8中,遍历Object.values(MyEnum)时,循环变量value会被逐个窄化为具体的枚举成员类型(MyEnum.A或MyEnum.B),因此MyGenericFunction<typeof value>会被实例化为对应成员的具体函数类型(比如(data: {a:string})=>void),与Functions类型中对应键的要求匹配。
  • 但在TypeScript 4.9中,Object.values(MyEnum)返回的类型被推断为MyEnum[](联合类型数组),循环变量value的类型始终是MyEnum(即MyEnum.A | MyEnum.B),而非单个成员类型。此时MyGenericFunction<typeof value>会被实例化为联合类型函数((data: {a:string})=>void) | ((data: {b:string})=>void)。
  • 由于Set的类型具有逆变特性,Set<联合类型函数>无法赋值给Set<具体成员函数>——前者的add方法允许添加任意一种联合类型的函数,而后者只允许添加对应具体成员的函数,TypeScript 4.9更严格地校验了这种类型不匹配,从而抛出错误。

内容的提问来源于stack exchange,提问作者Simon Tran

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 08:20:27