Closed
Description
var x: string|number;
// no error, x is number in else branch
var r4 = typeof x === "string" ? x.substr : x.toFixed;
// error, x is string|number in else branch
var r5 = typeof x === "string" && typeof x === "string" ? x.substr : x.toFixed;
Same behavior occurs in if/else. I believe the error is this logic in narrowTypeByAnd:
// The assumed result is false. This means either the first operand was false, or the first operand was true
// and the second operand was false. We narrow with those assumptions and union the two resulting types.
return getUnionType([
narrowType(type, expr.left, /*assumeTrue*/ false),
narrowType(narrowType(type, expr.left, /*assumeTrue*/ true), expr.right, /*assumeTrue*/ false)
]);