// @strictNullChecks: true type Item = Item1 | Item2; interface Base { bar: boolean; } interface Item1 extends Base { kind: "A"; foo: string | undefined; baz: boolean; qux: true; } interface Item2 extends Base { kind: "B"; foo: string | undefined; baz: boolean; qux: false; } function goo1(x: Item) { if (x.kind === "A" && x.foo !== undefined) { x.foo.length; } } function goo2(x: Item) { if (x.foo !== undefined && x.kind === "A") { x.foo.length; // Error, intervening discriminant guard } } function foo1(x: Item) { if (x.bar && x.foo !== undefined) { x.foo.length; } } function foo2(x: Item) { if (x.foo !== undefined && x.bar) { x.foo.length; } } function foo3(x: Item) { if (x.baz && x.foo !== undefined) { x.foo.length; } } function foo4(x: Item) { if (x.foo !== undefined && x.baz) { x.foo.length; } } function foo5(x: Item) { if (x.qux && x.foo !== undefined) { x.foo.length; } } function foo6(x: Item) { if (x.foo !== undefined && x.qux) { x.foo.length; // Error, intervening discriminant guard } } // Repro from #27493 enum Types { Str = 1, Num = 2 } type Instance = StrType | NumType; interface StrType { type: Types.Str; value: string; length: number; } interface NumType { type: Types.Num; value: number; } function func2(inst: Instance) { while (true) { switch (inst.type) { case Types.Str: { inst.value.length; break; } case Types.Num: { inst.value.toExponential; break; } } } } // Repro from #29106 const f = (_a: string, _b: string): void => {}; interface A { a?: string; b?: string; } interface B { a: string; b: string; } type U = A | B; const u: U = {} as any; u.a && u.b && f(u.a, u.b); u.b && u.a && f(u.a, u.b); // Repro from #29012 type Additive = '+' | '-'; type Multiplicative = '*' | '/'; interface AdditiveObj { key: Additive } interface MultiplicativeObj { key: Multiplicative } type Obj = AdditiveObj | MultiplicativeObj export function foo(obj: Obj) { switch (obj.key) { case '+': { onlyPlus(obj.key); return; } } } function onlyPlus(arg: '+') { return arg; } // Repro from #29496 declare function never(value: never): never; const enum BarEnum { bar1 = 1, bar2 = 2, } type UnionOfBar = TypeBar1 | TypeBar2; type TypeBar1 = { type: BarEnum.bar1 }; type TypeBar2 = { type: BarEnum.bar2 }; function func3(value: Partial) { if (value.type !== undefined) { switch (value.type) { case BarEnum.bar1: break; case BarEnum.bar2: break; default: never(value.type); } } }