TypeScript枚举新增成员时如何让对应对象数组触发类型错误
问题
如何修改类型定义,使得当我为枚举SomeEnum新增成员(例如Four、Five)时,TypeScript会抛出类型错误?
我知晓in运算符的用法,但它仅支持对键进行校验,无法应用于值的校验场景。
初始代码如下:
enum SomeEnum { One, Two, Three, Four, //<- 新增项 Five //<- 新增项 } // 修改value的类型定义,实现给SomeEnum加新成员(比如Four、Five)时TS自动报错 export const SomeConstant: {text: string, value: SomeEnum}[] = [ { text: 'One', value: SomeEnum.One }, { text: 'Two', value: SomeEnum.Two }, { text: 'Three', value: SomeEnum.Three }, ];
解决方案
核心逻辑是做枚举值穷尽校验:强制要求SomeConstant数组里的value字段覆盖SomeEnum的所有成员,一旦枚举新增成员但数组未补充对应项,就会触发类型不匹配错误。
方案1:追加类型校验行(侵入性最低)
不需要修改原有数组的定义逻辑,只需要在数组定义后追加2行校验代码即可:
enum SomeEnum { One, Two, Three, Four, // 新增后立刻触发类型错误 Five // 新增后立刻触发类型错误 } export const SomeConstant: {text: string, value: SomeEnum}[] = [ { text: 'One', value: SomeEnum.One }, { text: 'Two', value: SomeEnum.Two }, { text: 'Three', value: SomeEnum.Three }, ]; // 追加以下2行校验代码 type _CheckEnumCovered = SomeEnum extends typeof SomeConstant[number]['value'] ? true : false; const _enumCheck: true = null as unknown as _CheckEnumCovered;
实现逻辑:
typeof SomeConstant[number]['value']会自动推导数组中所有已使用的枚举值,组成联合类型- 如果枚举新增了成员但数组没同步补充,
SomeEnum extends 已使用值联合类型的判断结果为false,把false类型赋值给标注为true的_enumCheck变量时,TS会直接抛出类型错误,阻断编译。
该方案对数字枚举、字符串枚举都生效。
方案2:泛型工厂函数约束
如果希望在数组定义阶段就做约束,可以用泛型封装校验逻辑:
enum SomeEnum { One, Two, Three, Four, // 新增后立刻触发类型错误 Five // 新增后立刻触发类型错误 } // 穷尽校验工具类型 type ExhaustiveCheck<TEnum, TUsed> = TEnum extends TUsed ? TUsed extends TEnum ? {text: string, value: TEnum}[] : never : never; // 数组创建函数,内置类型校验 function createEnumConstants<TUsed extends SomeEnum>( arr: ExhaustiveCheck<SomeEnum, TUsed> ) { return arr; } // 定义数组时直接传入工厂函数,缺项就报错 export const SomeConstant = createEnumConstants([ { text: 'One', value: SomeEnum.One }, { text: 'Two', value: SomeEnum.Two }, { text: 'Three', value: SomeEnum.Three }, ]);
两种方案都能实现需求:只要给枚举新增成员、但没有同步给数组补充对应项,TS就会抛出类型错误。
内容的提问来源于stack exchange,提问作者AmirA
相关产品推荐
相关产品推荐

