首页 > 解决方案 > 代替字符串枚举,使用联合类型和静态声明

问题描述

在我看来,以下类型在 TypeScript 中比使用 Enums 更好。但是有没有办法简化这个?例如,我可能使用的实用程序类型。IMO 我们应该能够定义以这种方式工作的枚举,但据我所知,我们不能。

当前代码说明:

StepWizardEventType限制事件类型可以是的值,const用于在代码中访问值本身。const 的类型{ [prop: string]: StepWizardEventType } 允许将变量/属性键入StepWizardEventType并设置为 const 中的值之一stepWizardEventTypes

export type StepWizardEventType = 'cancel' | 'create' | 'init' | 'next' | 'previous' | 'reset' | 'save';

export const stepWizardEventTypes: { [Property in StepWizardEventType]: StepWizardEventType } = {
  cancel: 'cancel',
  create: 'create',
  init: 'init',
  next: 'next',
  previous: 'previous',
  reset: 'reset',
  save: 'save',
};

export interface StepEvent {
  type: StepWizardEventType;
}

// somewhere else in another file...

const event: StepEvent = {
  type: stepWizardEventTypes.cancel // compiler doesn't complain here! yay!
}

编辑:示例枚举使用使编译器不高兴。

export enum EventTypes {
  cancel = 'cancel',
  create = 'create'
}

type EventType = 'cancel' | 'create';

interface Dodad {
  eventType: EventType;
}

const doDadInstance: Dodad = {
  eventType: EventTypes.cancel // TypeScript complains here for enums
}

标签: typescript

解决方案


这是基于来自@jcalz 的反馈。仍然认为有简化的空间,但这更好。

type enumPropertyKey = { readonly [P in string]: P };

const makeIdEnum = <K extends string>(...kvs: K[]): enumPropertyKey => Object.fromEntries(
    kvs.map(kv => [kv, kv])
) as enumPropertyKey;

// example usage

const stepWizardEventTypes = makeIdEnum('cancel', 'create', 'init', 'next', 'previous', 'reset', 'save');
type StepWizardEventType = keyof typeof stepWizardEventTypes;

export interface StepEvent {
    type: StepWizardEventType;
}

// somewhere else in another file...

const event: StepEvent = {
    type: stepWizardEventTypes.cancel
}

推荐阅读