-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Compiler allows 'number' to be used where enum is expected #48296
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This is intentional because numeric enums are often used as bitfields, e.g. |
Can you provide a full line of code to demostrate what you've meant? I'm not sure how this is related to allowing implicitly assigning numbers into enum typed members. |
@RyanCavanaugh What is the justification for 'Working as Intended'? Especially in 'strict' mode? |
let computedFlags = FlagsEnum.One | FlagsEnum.Two;
obj.flagsEnum = computedFlags;
|
If you needed this type 'abuse' (in my opinion, sorry if too harsh :) ), you always could shut up the compiler explicitly:
So, fixing this TS compiler bug doesn't affect your use case and can't be the justification for the missing type safety related to enums in 'strict' mode. |
@AbakumovAlexandr because we did this behavior on purpose |
I’m not making any value judgments here, just telling you why the behavior is the way it is, and why it’s intentional. It’s also unlikely to change—at least, not without an additional opt-in compiler flag—as it would be pretty disruptive to a lot of code in the wild. |
Can you elaborate: what is the purpose? |
🤦♂️ |
So that you can use bitflag-style enums without getting an error, as described above. |
So, what should I do to ensure that the value in an enum-typed member is actually the one I've defined in my enum without any runtime code? |
There currently isn't a way to do that. The suggestion tracking adding a way to do so is #32690 |
Use a string-valued enum. |
You could also use a const StatusEnum = {
Cancelled: 4,
Paid: 6
} as const;
type StatusEnum = (typeof StatusEnum)[keyof typeof StatusEnum]; from there the code sample works as desired |
it's 3 years old :( TypeScript is intended to bring static type safety. At the same time, its default behavior is to implicitly allow If someone wants to assign a value into an enum member which doesn't exist in its definition (bit flags), doesn't it look like it is him who should explicitly tell it to the compiler? Or what's even the point of enumerating possible values of an enum, then? I just can't remember any other language with static types implicitly allowing this by default. |
This is how enums work in C++ and C#, too, fwiw. |
Of course, it's not true (https://dotnetfiddle.net/VnMaVJ), since a wider type can't be auto-converted into a narrower type in any statically-typed language: Otherwise as I said, there would be no point in narrow types (enums) if they would allow random non-existing in its definition values to be assigned. This behavior is simply implicit type breakage. |
Re: Statically-typed languages and correctness, at this point I'm just going to leave this here:
|
So what do you want to say by this exactly? 'The ability to assign the result of bit flagging with enums IMPLICITLY (when there's no problem to use Are you aware that such breakage leads to massive and undetectable at compile time issues with the whole type system? Which is much more counter-productive(!) than the above 'inconvenience'. How about this one?
|
This doesn't seem like a productive discussion. A trade-off was intentionally made; if you don't agree with the trade-off that's fine but there's no value to be found in reiterating all the same discussion points that occurred at the point of the decision. |
Bug Report
Compiler shouldn't allow
number
to be used whereenum
is expected.🔎 Search Terms
number where enum expected
🕗 Version & Regression Information
⏯ Playground Link
Playground link with relevant code
💻 Code
🙁 Actual behavior
Compiler allows
number
to be used whereenum
is expected. It's incorrect because narrowing conversion is done implicitly while the compiler cannot make sure that a value passed as the enum param is within a range of the enum values.🙂 Expected behavior
Implicit conversions from
number
toenum
should generate an error requiring an explicit conversion to be performed (for exampe, usingas
)The text was updated successfully, but these errors were encountered: