1// @strictNullChecks: true 2 3// Repro from #10257 plus other tests 4 5interface Foo { 6 kind: "foo"; 7 name: string; 8} 9 10interface Bar { 11 kind: "bar"; 12 length: string; 13} 14 15function f1(x: Foo | Bar | string) { 16 if (typeof x !== 'string') { 17 switch(x.kind) { 18 case 'foo': 19 x.name; 20 } 21 } 22} 23 24function f2(x: Foo | Bar | string | undefined) { 25 if (typeof x === "object") { 26 switch(x.kind) { 27 case 'foo': 28 x.name; 29 } 30 } 31} 32 33function f3(x: Foo | Bar | string | null) { 34 if (x && typeof x !== "string") { 35 switch(x.kind) { 36 case 'foo': 37 x.name; 38 } 39 } 40} 41 42function f4(x: Foo | Bar | string | number | null) { 43 if (x && typeof x === "object") { 44 switch(x.kind) { 45 case 'foo': 46 x.name; 47 } 48 } 49} 50 51// Repro from #31319 52 53const enum EnumTypeNode { 54 Pattern = "Pattern", 55 Disjunction = "Disjunction", 56} 57 58type NodeA = Disjunction | Pattern; 59 60interface NodeBase { 61 type: NodeA["type"] 62} 63 64interface Disjunction extends NodeBase { 65 type: EnumTypeNode.Disjunction 66 alternatives: string[] 67} 68 69interface Pattern extends NodeBase { 70 type: EnumTypeNode.Pattern 71 elements: string[] 72} 73 74let n!: NodeA 75 76if (n.type === "Disjunction") { 77 n.alternatives.slice() 78} 79else { 80 n.elements.slice() // n should be narrowed to Pattern 81} 82