(update 2021-06-10, this is unchanged by the TS4.3 update for union enums)
This is (maybe surprisingly) intended behavior. Numeric enums in TypeScript are sometimes used for bitwise operations, where the listed values are treated as flags. And, as stated by @RyanCavanaugh in a comment on a reported issue about this:
We don't distinguish between flag and non-flag enums, so a number that is above [or not equal to] any given enum member isn't necessarily invalid. For example
enum Flags {
Neat = 1,
Cool = 2,
Great = 4
}
// like saying Neat | Cool | Great
var x: Flags = 7;
So even though 7
is not equal to any one of the listed Flags
enum values, you can still get it by performing bitwise operations of the listed values. I'm pretty sure that the compiler doesn't do any restriction other than checking that the value is a number
.
In your case, even though none of the Something
enumerated values are 15
, it doesn't stop you from doing the (useless and dubiously sane) following:
const value: Something = (Something.Email | Something.All) >> 1;
which amounts to the same thing (10 | 20
evaluates to 30
, and 30 >> 1
is 15
).
Note that this bitwise stuff doesn't apply to string-based enums, so one way to deal with this is to change your numbers to string literals:
const enum Something {
None = '0',
Email = '10',
All = '20'
}
const value: Something = '15'; // error, as desired
and the compiler warns you that '15'
is not a valid value for Something
.
Hope that helps. Good luck!
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…