TypeScript Version: 3.3.0-dev.20190117
Search Terms: enum, casting enum, union type
Code
const enum Direction {
LEFT = "LEFT",
RIGHT = "RIGHT"
}
type DirectionType = "UP" | "DOWN" | Direction;
const myDirection: DirectionType = <Direction>"SOUTHWEST"; // no warning or error
Expected behavior:
Trying to assign "SOUTHWEST" to myDirection should give an error.
Actual behavior:
No warning or error.
The behaviour here is correct and the reason you are seeing no error is because you are using a _cast_.
<Direction>"SOUTHWEST";
If you remove the cast then you get the correct error:
const enum Direction {
LEFT = "LEFT",
RIGHT = "RIGHT"
}
type DirectionType = "UP" | "DOWN" | Direction;
// Error Below
// Type '"SOUTHWEST"' is not assignable to type 'DirectionType'.
const myDirection: DirectionType = "SOUTHWEST";
For safe interaction you should only assign from a type with more information to a type with less information; casts lets you travel in the other direction, which is unsafe, but sometimes needed.
This is basically a duplicate of #14156
@jack-williams Problem is, casting is the first thing to come in mind to assign const enum to union type.
In case you want to assign "LEFT", you would just code:
const myDirection: DirectionType = "LEFT";
which is not working as it would accept only Direction.LEFT as a valid assignment. So _casting_ looks the closest cousin for that assignment. Since it is 'working' making a typo would get it unnoticed as you expect its type safety.
Feel free to close, but a warning, or some other kind of protection would be a lot beneficial.
@bariscicek
Feel free to close, but a warning, or some other kind of protection would be a lot beneficial.
Just an FYI: I have zero affiliation with the TypeScript team so it's not for me to pass final judgment, or close any issues.
@ajafff is right, this is pretty much a duplicate I think; specifically, the union type isn't really relevant here. You have the same issue with:
const enum Direction {
LEFT = "LEFT",
RIGHT = "RIGHT"
}
type DirectionType = Direction; // NO UNION
const myDirection: DirectionType = <Direction>"SOUTHWEST"; // no warning or error
My opinion is that if something like this is a concern in your project, then a lint rule is the best way to go. I would suggest reading over the related issue (#14156) and if that doesn't answer all your questions, leave this issue open -- someone from the TS team can review it later.