• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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