Description
TypeScript Version: 2.3.4
When using union or enum types, the compiler changes the types of your local variables based on what it understands as the set of values that the variable could actually have taken on. While this proactive behavior could be helpful, it is impossible to opt-out of at present and can lead to complications and problems (which is hardly surprising, given that it literally changes the types of your variables to something other than what you declared them as).
Code
type MyEnum = "foo" | "bar" | "baz"
let myVal: MyEnum = "foo"
if (randomChance())
myVal = "bar"
if (myVal == "baz")
doStuff()
Expected behavior:
Compiles.
Actual behavior:
Line 8 throws an error, because the type of myVal
is "foo" | "bar"
, which isn't compatible with type "baz"
.
In this case, it is true that myVal
couldn't possibly have taken on the value "baz"
before that point, but in more complex examples, this behavior of the compiler yields a lot of false positives. It should absolutely be possible to disable this through a compiler flag (and perhaps this stricter check should be disabled by default).
It's worth noting that this can also be avoided by changing line 3 to let myVal = "foo" as MyEnum
, since then the compiler can't know what value myVal
was assigned in order to do this strict check.