Before TypeScript 2.0, the compiler did not use the control flow of the program for type guards. The easiest way to see what that means, is by an example:
function f(x: string | number) { if (typeof x === "string") { return; } x; }
The type guard narrows x
to string in the block after the if
statement. If the else block existed, it would have narrowed x
to number
there. Outside of the if statement, no narrowing happens, because the compiler only looks at the structure or shape of the program. That means that the type of x
on the last line would be string | number
, even though that line can only be executed if the condition of the if statement is false and x
can only be a number there. With some terminology, type guards were only syntax directed and were only based on the syntax, not on the control flow of the program.
As of TypeScript 2.0, the compiler can follow the control flow of the program. This gives more accurate...