Description
TypeScript Version: 2.5.2 & nightly (2.6.0-dev.20170929)
Code
interface A { type: "a", foo: string };
interface B { type: "b", foo: string | number };
function f(x: A | B) {
if (typeof x.foo === "number") return;
// x.foo: string
let y = x.type === "a" ? 1 : 2;
x.foo.substring(1, 2);
}
Expected behavior:
Given that the first line of the body of f
checks whether x.foo
is a string, the last line of the body should not cause an error.
Actual behavior:
The compiler shows an error on the last line of the body of f
, since the type of x.foo
is (wrongly) resolved to string | number
instead of string
. The type guard on the first line of f
is not considered.
file.ts(11,8): error TS2339: Property 'substring' does not exist on type 'string | number'.
I think that this happens because the compiler only searches for property type guards (on x.foo
in this case) until the last refinement on the related variable (in this case x
). It would be better if it would search until the last assignment, as type guards on x
should not break any refinement on properties.
Note that the correct behavior can be found when commenting the line that declares y
.