TypeScript中基于Enum配置变量:替代Switch-Case的优雅实现方案
问题
我拥有一个Enum类型变量Difficulty,希望在函数中根据该变量的值设置DifficultyConfig配置项。目前我想到的实现方式不够优雅,代码如下:
export interface DifficultyConfig { healthModifier: number, deathIsPermanent: boolean, } export interface AppProps { difficultyConfig: DifficultyConfig } export const NormalDifficultyConfig: DifficultyConfig = { enemyHealthModifier: 1, deathIsPermanent: false, } export const HigherDifficultyConfig: DifficultyConfig = { enemyHealthModifier: 1.3, deathIsPermanent: true, } export enum Difficulty { NORMAL = 'Normal', HARD = 'Hard', ADVANCED = 'Advanced', } function createApp(difficulty: Difficulty) { let difficultyConfig: DifficultyConfig; switch(difficulty) { case Difficulty.NORMAL: difficultyConfig = NormalDifficultyConfig; break; // Both HARD and ADVANCED get HigherDifficultyConfig case Difficulty.HARD: difficultyConfig = HigherDifficultyConfig; break; case Difficulty.ADVANCED: difficultyConfig = HigherDifficultyConfig; break; default: difficultyConfig = NormalDifficultyConfig; break; } return new App({ difficultyConfig }); }
我不喜欢在这种简单场景下使用Switch-Case语法,理想的实现方式类似Scala中的模式匹配写法:
val difficultyConfig = difficulty match { case Difficulty.NORMAL => NormalDifficultyConfig case Difficulty.HARD | Difficulty.ADVANCED => HigherDifficultyConfig case _ => NormalDifficultyConfig }
请问在JavaScript/TypeScript中是否存在与之等价的实现方式?
等价实现方式
当然有,以下是几种简洁且符合需求的实现方式:
1. 对象映射法(最常用,简洁直观)
通过创建键为Difficulty枚举值、值对应配置对象的映射表,直接通过键取值即可,多值复用同一配置的场景能清晰体现:
// 定义映射关系 const difficultyConfigMap: Record<Difficulty, DifficultyConfig> = { [Difficulty.NORMAL]: NormalDifficultyConfig, [Difficulty.HARD]: HigherDifficultyConfig, [Difficulty.ADVANCED]: HigherDifficultyConfig, }; function createApp(difficulty: Difficulty) { // 取值并设置默认值,空值合并运算符`??`确保兜底逻辑 const difficultyConfig = difficultyConfigMap[difficulty] ?? NormalDifficultyConfig; return new App({ difficultyConfig }); }
2. 规则数组匹配法(贴近模式匹配写法)
用数组存储匹配规则,每条规则包含要匹配的枚举值集合和对应的配置,通过find方法找到第一个匹配的规则,适合后续扩展复杂匹配条件:
function createApp(difficulty: Difficulty) { const difficultyConfig = [ { matches: [Difficulty.NORMAL], config: NormalDifficultyConfig }, { matches: [Difficulty.HARD, Difficulty.ADVANCED], config: HigherDifficultyConfig }, ] .find(rule => rule.matches.includes(difficulty))?.config ?? NormalDifficultyConfig; return new App({ difficultyConfig }); }
3. 简洁条件判断法(极简单场景适用)
如果场景非常简单,也可以用三元运算符组合逻辑,代码量极少:
function createApp(difficulty: Difficulty) { const difficultyConfig = difficulty === Difficulty.NORMAL ? NormalDifficultyConfig : HigherDifficultyConfig; // 额外兜底逻辑(处理未定义的枚举值) return new App({ difficultyConfig: difficultyConfig ?? NormalDifficultyConfig }); }
内容的提问来源于stack exchange,提问作者Paul Eaten
相关产品推荐
相关产品推荐

