如何在TypeScript 4.9中检查所有枚举值是否被对象使用?
实现方案(TypeScript 4.9)
要实现VALUES枚举新增值时触发编译错误,我们可以通过辅助条件类型结合原有的映射类型实现双重约束——既保证KEYS的所有键都被定义,又确保VALUES的所有值都被用到。
步骤1:定义辅助检查类型
这个类型会验证传入的映射对象是否包含了VALUES的所有枚举值:
type EnsureAllValuesAreUsed<T> = T extends { [K in KEYS]: VALUES[] } ? Exclude<VALUES, T[keyof T][number]> extends never ? T : never : never;
T[keyof T][number]:提取映射对象中所有数组元素的联合类型(即已被使用的VALUES值)Exclude<VALUES, ...>:找出VALUES中未被使用的枚举值,如果结果是never,说明所有值都已被覆盖- 只有当所有
VALUES值都被使用时,类型才返回原映射类型;否则返回never,触发编译错误
步骤2:为mapping添加类型约束
我们可以用两种方式应用这个约束:
方式一:直接使用类型注解
enum VALUES { val1 = 'val1', val2 = 'val2', // 新增val3时,如果mapping里没用到就会报错 val3 = 'val3' } enum KEYS { key1 = 'key1', key2 = 'key2' } const mapping: EnsureAllValuesAreUsed<{ readonly [i in KEYS]: VALUES[] }> = { [KEYS.key1]: [VALUES.val1, VALUES.val3], // 必须包含val3 [KEYS.key2]: [VALUES.val2, VALUES.val1], };
方式二:用satisfies操作符(TS4.9支持)
这种方式能保留原映射类型的自动提示,同时添加约束:
const mapping = { [KEYS.key1]: [VALUES.val1, VALUES.val3], [KEYS.key2]: [VALUES.val2, VALUES.val1], } satisfies EnsureAllValuesAreUsed<{ readonly [i in KEYS]: VALUES[] }>;
效果验证
当你在VALUES中新增val3但没在mapping的任何数组里使用时,TypeScript会抛出编译错误,提示你无法将映射对象赋值给never类型,从而强制你必须使用新的枚举值。
内容的提问来源于stack exchange,提问作者farzad
相关产品推荐
相关产品推荐

