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

TypeScript类型映射中keyof推导异常的原因排查

问题原因与解决方法

核心问题

你这里的核心错误是EnumTypes的定义方向搞反了:你在里面存的是枚举值的联合类型(MyEnum是1|2,MyEnum2是'a'|'b'),但keyof作用在数字、字符串这类原始类型上时,TypeScript会返回其包装对象的内置方法名(比如数字的toString、toFixed,字符串的charAt等),这就是你看到那些奇怪键的原因。

你真正需要关联的不是枚举值类型,而是枚举对象的类型(也就是typeof MyEnum和typeof MyEnum2),只有枚举对象的类型才包含你自定义的键(AAA/BBB、a/b)。

修正后的代码

先修正EnumTypes的定义,让它映射到枚举对象的类型:

type MyEnum = 1 | 2 ; 
const MyEnum = { 
    AAA: 1 as MyEnum, 
    BBB: 2 as MyEnum,
}

type MyEnum2 = 'a' | 'b' ; 
const MyEnum2 = { 
    a: 'a' as MyEnum2, 
    b: 'b' as MyEnum2,
}

// 修正:这里存储枚举对象的类型(typeof 枚举对象)
type EnumTypes = {
  myenum: typeof MyEnum;
  myenum2: typeof MyEnum2;
}

// 此时B的类型会自动对应枚举对象的合法键
function getB<E extends keyof EnumTypes, B extends keyof EnumTypes[E]>(e: E, key: B) {
    console.log(e, key);
}

// 现在类型检查完全正常
getB("myenum", "AAA"); // 合法
getB("myenum", "BBB"); // 合法
getB("myenum2", "a"); // 合法
getB("myenum", "a"); // 类型报错(符合预期)

补充说明

你之前的重载写法之所以能工作,是因为直接指定了B extends keyof typeof MyEnum——明确取的是枚举对象的键类型,而非枚举值类型。修正后的通用写法和重载效果一致,但更灵活,新增枚举时不需要额外添加重载声明。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 06:20:12