Skip to content

Commit 6fd2874

Browse files
authored
Use comparability for discriminant properties when narrowing types for a default switch clause (#61211)
1 parent 2a90a73 commit 6fd2874

File tree

4 files changed

+540
-1
lines changed

4 files changed

+540
-1
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29739,7 +29739,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2973929739
if (!hasDefaultClause) {
2974029740
return caseType;
2974129741
}
29742-
const defaultType = filterType(type, t => !(isUnitLikeType(t) && contains(switchTypes, t.flags & TypeFlags.Undefined ? undefinedType : getRegularTypeOfLiteralType(extractUnitType(t)))));
29742+
const defaultType = filterType(type, t => !(isUnitLikeType(t) && contains(switchTypes, t.flags & TypeFlags.Undefined ? undefinedType : getRegularTypeOfLiteralType(extractUnitType(t)), (t1, t2) => isUnitType(t1) && areTypesComparable(t1, t2))));
2974329743
return caseType.flags & TypeFlags.Never ? defaultType : getUnionType([caseType, defaultType]);
2974429744
}
2974529745

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
//// [tests/cases/conformance/types/union/discriminatedUnionTypes4.ts] ////
2+
3+
=== discriminatedUnionTypes4.ts ===
4+
// https://github.com/microsoft/TypeScript/issues/61207
5+
6+
enum AnimalType {
7+
>AnimalType : Symbol(AnimalType, Decl(discriminatedUnionTypes4.ts, 0, 0))
8+
9+
cat = "cat",
10+
>cat : Symbol(AnimalType.cat, Decl(discriminatedUnionTypes4.ts, 2, 17))
11+
12+
dog = "dog",
13+
>dog : Symbol(AnimalType.dog, Decl(discriminatedUnionTypes4.ts, 3, 14))
14+
}
15+
16+
type Animal =
17+
>Animal : Symbol(Animal, Decl(discriminatedUnionTypes4.ts, 5, 1))
18+
19+
| {
20+
type: `${AnimalType.cat}`;
21+
>type : Symbol(type, Decl(discriminatedUnionTypes4.ts, 8, 5))
22+
>AnimalType : Symbol(AnimalType, Decl(discriminatedUnionTypes4.ts, 0, 0))
23+
>cat : Symbol(AnimalType.cat, Decl(discriminatedUnionTypes4.ts, 2, 17))
24+
25+
meow: string;
26+
>meow : Symbol(meow, Decl(discriminatedUnionTypes4.ts, 9, 32))
27+
}
28+
| {
29+
type: `${AnimalType.dog}`;
30+
>type : Symbol(type, Decl(discriminatedUnionTypes4.ts, 12, 5))
31+
>AnimalType : Symbol(AnimalType, Decl(discriminatedUnionTypes4.ts, 0, 0))
32+
>dog : Symbol(AnimalType.dog, Decl(discriminatedUnionTypes4.ts, 3, 14))
33+
34+
bark: string;
35+
>bark : Symbol(bark, Decl(discriminatedUnionTypes4.ts, 13, 32))
36+
37+
};
38+
39+
function check(p: never) {
40+
>check : Symbol(check, Decl(discriminatedUnionTypes4.ts, 15, 6))
41+
>p : Symbol(p, Decl(discriminatedUnionTypes4.ts, 17, 15))
42+
43+
throw new Error("Error!");
44+
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
45+
}
46+
47+
function action1(animal: Animal) {
48+
>action1 : Symbol(action1, Decl(discriminatedUnionTypes4.ts, 19, 1))
49+
>animal : Symbol(animal, Decl(discriminatedUnionTypes4.ts, 21, 17))
50+
>Animal : Symbol(Animal, Decl(discriminatedUnionTypes4.ts, 5, 1))
51+
52+
if (animal.type === AnimalType.cat) {
53+
>animal.type : Symbol(type, Decl(discriminatedUnionTypes4.ts, 8, 5), Decl(discriminatedUnionTypes4.ts, 12, 5))
54+
>animal : Symbol(animal, Decl(discriminatedUnionTypes4.ts, 21, 17))
55+
>type : Symbol(type, Decl(discriminatedUnionTypes4.ts, 8, 5), Decl(discriminatedUnionTypes4.ts, 12, 5))
56+
>AnimalType.cat : Symbol(AnimalType.cat, Decl(discriminatedUnionTypes4.ts, 2, 17))
57+
>AnimalType : Symbol(AnimalType, Decl(discriminatedUnionTypes4.ts, 0, 0))
58+
>cat : Symbol(AnimalType.cat, Decl(discriminatedUnionTypes4.ts, 2, 17))
59+
60+
console.log(animal.meow);
61+
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
62+
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
63+
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
64+
>animal.meow : Symbol(meow, Decl(discriminatedUnionTypes4.ts, 9, 32))
65+
>animal : Symbol(animal, Decl(discriminatedUnionTypes4.ts, 21, 17))
66+
>meow : Symbol(meow, Decl(discriminatedUnionTypes4.ts, 9, 32))
67+
68+
} else if (animal.type === AnimalType.dog) {
69+
>animal.type : Symbol(type, Decl(discriminatedUnionTypes4.ts, 12, 5))
70+
>animal : Symbol(animal, Decl(discriminatedUnionTypes4.ts, 21, 17))
71+
>type : Symbol(type, Decl(discriminatedUnionTypes4.ts, 12, 5))
72+
>AnimalType.dog : Symbol(AnimalType.dog, Decl(discriminatedUnionTypes4.ts, 3, 14))
73+
>AnimalType : Symbol(AnimalType, Decl(discriminatedUnionTypes4.ts, 0, 0))
74+
>dog : Symbol(AnimalType.dog, Decl(discriminatedUnionTypes4.ts, 3, 14))
75+
76+
console.log(animal.bark);
77+
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
78+
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
79+
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
80+
>animal.bark : Symbol(bark, Decl(discriminatedUnionTypes4.ts, 13, 32))
81+
>animal : Symbol(animal, Decl(discriminatedUnionTypes4.ts, 21, 17))
82+
>bark : Symbol(bark, Decl(discriminatedUnionTypes4.ts, 13, 32))
83+
84+
} else {
85+
check(animal);
86+
>check : Symbol(check, Decl(discriminatedUnionTypes4.ts, 15, 6))
87+
>animal : Symbol(animal, Decl(discriminatedUnionTypes4.ts, 21, 17))
88+
}
89+
}
90+
91+
function action2(animal: Animal) {
92+
>action2 : Symbol(action2, Decl(discriminatedUnionTypes4.ts, 29, 1))
93+
>animal : Symbol(animal, Decl(discriminatedUnionTypes4.ts, 31, 17))
94+
>Animal : Symbol(Animal, Decl(discriminatedUnionTypes4.ts, 5, 1))
95+
96+
switch (animal.type) {
97+
>animal.type : Symbol(type, Decl(discriminatedUnionTypes4.ts, 8, 5), Decl(discriminatedUnionTypes4.ts, 12, 5))
98+
>animal : Symbol(animal, Decl(discriminatedUnionTypes4.ts, 31, 17))
99+
>type : Symbol(type, Decl(discriminatedUnionTypes4.ts, 8, 5), Decl(discriminatedUnionTypes4.ts, 12, 5))
100+
101+
case `${AnimalType.cat}`:
102+
>AnimalType.cat : Symbol(AnimalType.cat, Decl(discriminatedUnionTypes4.ts, 2, 17))
103+
>AnimalType : Symbol(AnimalType, Decl(discriminatedUnionTypes4.ts, 0, 0))
104+
>cat : Symbol(AnimalType.cat, Decl(discriminatedUnionTypes4.ts, 2, 17))
105+
106+
console.log(animal.meow);
107+
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
108+
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
109+
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
110+
>animal.meow : Symbol(meow, Decl(discriminatedUnionTypes4.ts, 9, 32))
111+
>animal : Symbol(animal, Decl(discriminatedUnionTypes4.ts, 31, 17))
112+
>meow : Symbol(meow, Decl(discriminatedUnionTypes4.ts, 9, 32))
113+
114+
break;
115+
case `${AnimalType.dog}`:
116+
>AnimalType.dog : Symbol(AnimalType.dog, Decl(discriminatedUnionTypes4.ts, 3, 14))
117+
>AnimalType : Symbol(AnimalType, Decl(discriminatedUnionTypes4.ts, 0, 0))
118+
>dog : Symbol(AnimalType.dog, Decl(discriminatedUnionTypes4.ts, 3, 14))
119+
120+
console.log(animal.bark);
121+
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
122+
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
123+
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
124+
>animal.bark : Symbol(bark, Decl(discriminatedUnionTypes4.ts, 13, 32))
125+
>animal : Symbol(animal, Decl(discriminatedUnionTypes4.ts, 31, 17))
126+
>bark : Symbol(bark, Decl(discriminatedUnionTypes4.ts, 13, 32))
127+
128+
break;
129+
default:
130+
check(animal);
131+
>check : Symbol(check, Decl(discriminatedUnionTypes4.ts, 15, 6))
132+
>animal : Symbol(animal, Decl(discriminatedUnionTypes4.ts, 31, 17))
133+
}
134+
}
135+
136+
function action3(animal: Animal) {
137+
>action3 : Symbol(action3, Decl(discriminatedUnionTypes4.ts, 42, 1))
138+
>animal : Symbol(animal, Decl(discriminatedUnionTypes4.ts, 44, 17))
139+
>Animal : Symbol(Animal, Decl(discriminatedUnionTypes4.ts, 5, 1))
140+
141+
switch (animal.type) {
142+
>animal.type : Symbol(type, Decl(discriminatedUnionTypes4.ts, 8, 5), Decl(discriminatedUnionTypes4.ts, 12, 5))
143+
>animal : Symbol(animal, Decl(discriminatedUnionTypes4.ts, 44, 17))
144+
>type : Symbol(type, Decl(discriminatedUnionTypes4.ts, 8, 5), Decl(discriminatedUnionTypes4.ts, 12, 5))
145+
146+
case AnimalType.cat:
147+
>AnimalType.cat : Symbol(AnimalType.cat, Decl(discriminatedUnionTypes4.ts, 2, 17))
148+
>AnimalType : Symbol(AnimalType, Decl(discriminatedUnionTypes4.ts, 0, 0))
149+
>cat : Symbol(AnimalType.cat, Decl(discriminatedUnionTypes4.ts, 2, 17))
150+
151+
console.log(animal.meow);
152+
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
153+
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
154+
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
155+
>animal.meow : Symbol(meow, Decl(discriminatedUnionTypes4.ts, 9, 32))
156+
>animal : Symbol(animal, Decl(discriminatedUnionTypes4.ts, 44, 17))
157+
>meow : Symbol(meow, Decl(discriminatedUnionTypes4.ts, 9, 32))
158+
159+
break;
160+
case AnimalType.dog:
161+
>AnimalType.dog : Symbol(AnimalType.dog, Decl(discriminatedUnionTypes4.ts, 3, 14))
162+
>AnimalType : Symbol(AnimalType, Decl(discriminatedUnionTypes4.ts, 0, 0))
163+
>dog : Symbol(AnimalType.dog, Decl(discriminatedUnionTypes4.ts, 3, 14))
164+
165+
console.log(animal.bark);
166+
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
167+
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
168+
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
169+
>animal.bark : Symbol(bark, Decl(discriminatedUnionTypes4.ts, 13, 32))
170+
>animal : Symbol(animal, Decl(discriminatedUnionTypes4.ts, 44, 17))
171+
>bark : Symbol(bark, Decl(discriminatedUnionTypes4.ts, 13, 32))
172+
173+
break;
174+
default:
175+
check(animal);
176+
>check : Symbol(check, Decl(discriminatedUnionTypes4.ts, 15, 6))
177+
>animal : Symbol(animal, Decl(discriminatedUnionTypes4.ts, 44, 17))
178+
}
179+
}
180+

0 commit comments

Comments
 (0)