TypeScript中获取const enum值的联合类型并避免重复定义
解决TypeScript中Const Enum与联合类型重复定义的问题
核心思路
先定义const enum枚举值(与后端返回的fieldType字符串完全对齐),再基于枚举自动生成联合类型,彻底避免手动重复写字符串。同时针对JSON解析场景的类型兼容问题做针对性处理。
正确实现代码
// 定义const enum,枚举值与后端返回的fieldType字符串完全一致 const enum FieldTypesEnum { Input = 'input', Select = 'select', Checkbox = 'checkbox', DatePicker = 'datePicker' } // 基于enum自动生成联合类型,无需手动维护字符串集合 type FieldType = `${FieldTypesEnum}`; // 基础字段接口 interface BaseField { fieldType: FieldType; label: string; } // 各类型字段的专属接口 interface InputField extends BaseField { fieldType: typeof FieldTypesEnum.Input; placeholder: string; } interface SelectField extends BaseField { fieldType: typeof FieldTypesEnum.Select; options: { label: string; value: string }[]; } interface CheckboxField extends BaseField { fieldType: typeof FieldTypesEnum.Checkbox; checked: boolean; } // 所有表单字段的联合类型 type FormField = InputField | SelectField | CheckboxField;
解决编译报错的关键处理
场景1:后端JSON字符串与枚举类型不兼容
后端返回的是原始字符串,直接赋值会触发类型不匹配报错,需要用类型守卫做校验转换:
// 校验字符串是否为有效FieldType的类型守卫 function isValidFieldType(type: string): type is FieldType { return Object.values(FieldTypesEnum).includes(type as FieldTypesEnum); } // 解析后端返回的表单字段 const parseFormField = (raw: unknown): FormField | null => { if (typeof raw !== 'object' || raw === null || !('fieldType' in raw)) { return null; } const rawField = raw as Record<string, unknown>; if (typeof rawField.fieldType !== 'string' || !isValidFieldType(rawField.fieldType)) { return null; } return rawField as FormField; };
场景2:const enum导致的类型推导失败
之前用type FieldType = typeof FieldTypesEnum[keyof typeof FieldTypesEnum]报错,是因为const enum编译时会被完全擦除,TypeScript无法通过typeof获取其值类型。而用模板字符串类型${FieldTypesEnum},会直接基于枚举的字面量值生成字符串联合类型,不受const enum擦除机制的影响。
场景3:直接用enum替代联合类型的报错
直接用FieldTypesEnum代替联合类型时,后端字符串无法直接赋值——TypeScript会严格区分枚举成员和原始字符串。而自动生成的FieldType是字符串字面量联合,既能兼容枚举成员赋值,也能直接接受后端返回的原始字符串。
内容的提问来源于stack exchange,提问作者KirillGordineRhenag
相关产品推荐
相关产品推荐

