TypeScript枚举值数组类型赋值错误未触发校验报错问题
数字枚举赋值未触发类型报错的原因
这是TypeScript针对数字枚举的默认设计行为,不是类型检查漏洞。
- 数字枚举的类型检查规则本身是宽松的:TypeScript中数字枚举的类型被视为
number的子类型,但不会对赋值做枚举成员值的范围校验。不止数组场景,直接写const val: AnimalId = 4也不会触发类型错误,本质是TS默认允许任意number值赋值给数字枚举类型。 - 这种宽松设计是为了兼容枚举的位运算使用场景:数字枚举最常见的用法之一是通过位运算组合多个枚举值,生成一个不在枚举显式声明列表里的新数值,比如权限控制场景:
enum Permission { Read = 1, Write = 2, Execute = 4 } // 组合后的值为7,不在枚举显式定义的成员值中,是完全合法的业务用法 const fullAccess: Permission = Permission.Read | Permission.Write | Permission.Execute;
如果TS强制要求数字枚举的赋值必须是显式声明的成员值,这类通用写法会直接失效,因此TS默认没有开启这类严格校验。
- 如果需要严格限制赋值只能是枚举中显式定义的成员,有两种通用实现方式:
- 改用字符串枚举:TS对字符串枚举执行严格的成员值校验,传入未定义的字符串会直接抛出类型错误:
enum AnimalId { Dog = 'dog', Cat = 'cat' } // 以下代码会触发类型错误 const animalIds: AnimalId[] = [AnimalId.Dog, 'other'];- 基于现有数字枚举生成严格的联合字面量类型:把枚举成员本身组成联合类型,就能触发严格的字面量校验:
enum AnimalId { Dog = 2, Cat = 3 } type StrictAnimalId = AnimalId.Dog | AnimalId.Cat; // 以下代码会触发类型错误,提示4无法赋值给StrictAnimalId类型 const animalIds: StrictAnimalId[] = [AnimalId.Dog, 4];
内容的提问来源于stack exchange,提问作者tymeq
相关产品推荐
相关产品推荐

