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

TypeScript能否基于基础枚举派生首字母大写的成员枚举?

如何从基础枚举派生大小写不同的枚举?

需求场景

我们正在构建一项服务,流程如下:

  • 接收输入,例如{titleDe: 'Lorem', titleFr: 'Ipsum'}
  • 返回目标语言(如'de')对应的所有带后缀属性
  • 输出结果:{title: 'Lorem'}

当前实现的痛点

目前我们用两个枚举分别处理语言校验和后缀匹配:

语言校验枚举

export enum Language {
  DE = 'de',
  IT = 'it',
  FR = 'fr',
  EN = 'en',
}

语言后缀枚举

export enum LanguageSuffix {
  DE = 'De',
  IT = 'It',
  FR = 'Fr',
  EN = 'En',
}

这两个枚举仅成员值的大小写不同,需要重复维护,非常麻烦。之前尝试过enum LanguageSuffix { DE = Capitalize<Language> },但因为类型和值不匹配无法生效,想找个办法从基础枚举直接派生另一个。

可行解决方案

1. 用对象+类型别名替代枚举(推荐)

TypeScript的枚举本质上是对象,我们可以先定义基础的语言配置对象,再自动派生后缀对象,同时生成对应的类型:

// 基础语言配置,只需要维护这一个
const Language = {
  DE: 'de',
  IT: 'it',
  FR: 'fr',
  EN: 'en',
} as const;

// 自动派生后缀对象
const LanguageSuffix = Object.fromEntries(
  Object.entries(Language).map(([key, value]) => [
    key,
    value.charAt(0).toUpperCase() + value.slice(1)
  ])
) as { [K in keyof typeof Language]: Capitalize<typeof Language[K]> };

// 生成对应的类型别名,保留类型校验能力
type Language = typeof Language[keyof typeof Language];
type LanguageSuffix = typeof LanguageSuffix[keyof typeof LanguageSuffix];

这样只需要维护Language对象,LanguageSuffix会自动同步更新,同时完全保留原有的类型校验功能。

2. 保留枚举+工具函数动态生成后缀

如果一定要用枚举形式,可以只维护Language枚举,通过工具函数动态转换得到后缀:

export enum Language {
  DE = 'de',
  IT = 'it',
  FR = 'fr',
  EN = 'en',
}

// 工具函数:把语言标识转换为对应的后缀
function getLanguageSuffix(lang: Language): Capitalize<Language> {
  return (lang.charAt(0).toUpperCase() + lang.slice(1)) as Capitalize<Language>;
}

// 使用示例
const deSuffix = getLanguageSuffix(Language.DE); // 类型为'De',值也是'De'

这种方式不需要维护第二个枚举,直接通过函数转换就能得到正确的后缀,同时Capitalize工具类型保证了返回值的类型正确性。

3. 利用TypeScript 5.0+的枚举合并特性

如果你的项目使用TypeScript 5.0及以上版本,可以用枚举合并来派生:

export enum Language {
  DE = 'de',
  IT = 'it',
  FR = 'fr',
  EN = 'en',
}

// 先声明空的后缀枚举
export enum LanguageSuffix {}
// 动态赋值,从Language枚举派生后缀
Object.assign(LanguageSuffix, Object.fromEntries(
  Object.entries(Language).map(([key, value]) => [
    key,
    value.charAt(0).toUpperCase() + value.slice(1)
  ])
));

// 为后缀枚举添加类型声明
type LanguageSuffix = Capitalize<Language>;

这种方式保留了枚举的语法形式,同时避免了手动重复编写成员。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 07:52:41