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

TypeScript枚举遍历:仅用枚举键创建Skill实例并添加至数组

解决枚举遍历与反向映射问题

首先,我注意到你当前的枚举写法用了<any>类型断言,这会让TypeScript为这个字符串值的枚举生成双向映射(也就是你提到的反向映射),但这也导致for...in遍历时会同时拿到枚举的原始键(如ACROBATICS)和反向映射的键(如"Acrobatics")。我们可以分两步解决你的需求:只使用枚举键创建Skill实例,同时保留反向映射功能。

方案一:使用标准字符串枚举 + 手动创建反向映射

TypeScript的字符串枚举默认不会生成反向映射,所以我们可以先修正枚举的写法,然后手动构建反向映射对象,这样既干净又能满足需求:

// 标准字符串枚举,无自动反向映射
enum eSkills {
  ACROBATICS = "Acrobatics",
  APPRAISE = "Appraise",
  BLUFF = "Bluff",
  CLIMB = "Climb",
  CRAFT = "Craft"
}

class Skill {
  constructor(name: eSkills) {
    this.name = name;
  }
  name: eSkills;
}

// 手动创建反向映射:通过技能显示名称获取枚举键
const eSkillsReverse: Record<eSkills, keyof typeof eSkills> = Object.fromEntries(
  Object.entries(eSkills).map(([key, value]) => [value, key])
) as Record<eSkills, keyof typeof eSkills>;

let skills: Skill[] = [];
// 遍历枚举的原始键,创建Skill实例
for (const skillKey in eSkills) {
  const skillEnumValue = eSkills[skillKey as keyof typeof eSkills];
  skills.push(new Skill(skillEnumValue));
}

// 测试反向映射
console.log(eSkillsReverse["Acrobatics"]); // 输出 "ACROBATICS"

方案二:保留现有枚举写法,过滤反向映射键

如果你想保留当前使用<any>的枚举写法(它会自动生成双向映射),那么在遍历时需要过滤掉反向映射的键。我们可以通过判断键是否等于其大写形式(因为你的枚举键都是大写,反向映射的键是首字母大写的显示名称)来过滤:

enum eSkills {
  ACROBATICS = <any>"Acrobatics",
  APPRAISE = <any>"Appraise",
  BLUFF = <any>"Bluff",
  CLIMB = <any>"Climb",
  CRAFT = <any>"Craft"
}

class Skill {
  constructor(name: eSkills) {
    this.name = name;
  }
  name: eSkills;
}

let skills: Skill[] = [];
for (let skill in eSkills) {
  // 过滤掉反向映射的键(仅保留大写的枚举原始键)
  if (skill === skill.toUpperCase()) {
    skills.push(new Skill(eSkills[skill] as eSkills));
  }
}

// 测试自动生成的反向映射
console.log(eSkills["Acrobatics"]); // 输出 "ACROBATICS"

小提示

  • 方案一的标准字符串枚举更符合TypeScript的最佳实践,手动创建的反向映射也更可控,避免了<any>带来的类型不安全。
  • 方案二的过滤逻辑依赖枚举键的命名规范(全大写),如果后续枚举键命名变化,需要同步调整过滤条件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:03:29