Skip to content

Commit 4263285

Browse files
Merge pull request microsoft#28780 from Microsoft/singlyOverlappyTypes
Singly overlappy types
2 parents 01f77f7 + 8e98943 commit 4263285

7 files changed

+210
-8
lines changed

src/compiler/checker.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11977,7 +11977,7 @@ namespace ts {
1197711977
matchingCount = Infinity;
1197811978
}
1197911979
else if (overlap.flags & TypeFlags.Union) {
11980-
// Some subset overlap if we have only string literals.
11980+
// We only want to account for literal types otherwise.
1198111981
// If we have a union of index types, it seems likely that we
1198211982
// needed to elaborate between two generic mapped types anyway.
1198311983
const len = length(filter((overlap as UnionType).types, isUnitType));
@@ -11986,7 +11986,7 @@ namespace ts {
1198611986
matchingCount = len;
1198711987
}
1198811988
}
11989-
else if (!(overlap.flags & TypeFlags.Never) && 1 >= matchingCount) {
11989+
else if (isUnitType(overlap) && 1 >= matchingCount) {
1199011990
bestMatch = target;
1199111991
matchingCount = 1;
1199211992
}

tests/baselines/reference/errorsOnUnionsOfOverlappingObjects01.errors.txt

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,17 @@ tests/cases/compiler/errorsOnUnionsOfOverlappingObjects01.ts(19,3): error TS2345
88
Type 'string' is not assignable to type 'number'.
99
tests/cases/compiler/errorsOnUnionsOfOverlappingObjects01.ts(24,5): error TS2345: Argument of type '{ a: string; b: string; }' is not assignable to parameter of type 'Bar | Other'.
1010
Object literal may only specify known properties, and 'a' does not exist in type 'Bar | Other'.
11+
tests/cases/compiler/errorsOnUnionsOfOverlappingObjects01.ts(42,10): error TS2345: Argument of type '{ dog: string; }' is not assignable to parameter of type 'ExoticAnimal'.
12+
Property 'cat' is missing in type '{ dog: string; }' but required in type 'CatDog'.
13+
tests/cases/compiler/errorsOnUnionsOfOverlappingObjects01.ts(43,10): error TS2345: Argument of type '{ man: string; bear: string; }' is not assignable to parameter of type 'ExoticAnimal'.
14+
Property 'pig' is missing in type '{ man: string; bear: string; }' but required in type 'ManBearPig'.
15+
tests/cases/compiler/errorsOnUnionsOfOverlappingObjects01.ts(46,26): error TS2345: Argument of type '{ man: string; beer: string; }' is not assignable to parameter of type 'ExoticAnimal'.
16+
Object literal may only specify known properties, and 'beer' does not exist in type 'ExoticAnimal'.
17+
tests/cases/compiler/errorsOnUnionsOfOverlappingObjects01.ts(47,10): error TS2345: Argument of type '{ man: string; beer: string; }' is not assignable to parameter of type 'ExoticAnimal'.
18+
Type '{ man: string; beer: string; }' is missing the following properties from type 'ManBearPig': bear, pig
1119

1220

13-
==== tests/cases/compiler/errorsOnUnionsOfOverlappingObjects01.ts (3 errors) ====
21+
==== tests/cases/compiler/errorsOnUnionsOfOverlappingObjects01.ts (7 errors) ====
1422
interface Foo {
1523
a: string;
1624
b: number;
@@ -53,4 +61,35 @@ tests/cases/compiler/errorsOnUnionsOfOverlappingObjects01.ts(24,5): error TS2345
5361

5462
h(x);
5563
h({ a: '', b: '' })
56-
64+
65+
interface CatDog { cat: any, dog: any }
66+
interface ManBearPig { man: any, bear: any, pig: any }
67+
interface Platypus { platypus: any }
68+
69+
type ExoticAnimal =
70+
| CatDog
71+
| ManBearPig
72+
| Platypus;
73+
74+
declare function addToZoo(animal: ExoticAnimal): void;
75+
76+
addToZoo({ dog: "Barky McBarkface" });
77+
~~~~~~~~~~~~~~~~~~~~~~~~~~~
78+
!!! error TS2345: Argument of type '{ dog: string; }' is not assignable to parameter of type 'ExoticAnimal'.
79+
!!! error TS2345: Property 'cat' is missing in type '{ dog: string; }' but required in type 'CatDog'.
80+
!!! related TS2728 tests/cases/compiler/errorsOnUnionsOfOverlappingObjects01.ts:31:20: 'cat' is declared here.
81+
addToZoo({ man: "Manny", bear: "Coffee" });
82+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
83+
!!! error TS2345: Argument of type '{ man: string; bear: string; }' is not assignable to parameter of type 'ExoticAnimal'.
84+
!!! error TS2345: Property 'pig' is missing in type '{ man: string; bear: string; }' but required in type 'ManBearPig'.
85+
!!! related TS2728 tests/cases/compiler/errorsOnUnionsOfOverlappingObjects01.ts:32:45: 'pig' is declared here.
86+
87+
const manBeer = { man: "Manny", beer: "Coffee" };
88+
addToZoo({ man: "Manny", beer: "Coffee" });
89+
~~~~~~~~~~~~~~
90+
!!! error TS2345: Argument of type '{ man: string; beer: string; }' is not assignable to parameter of type 'ExoticAnimal'.
91+
!!! error TS2345: Object literal may only specify known properties, and 'beer' does not exist in type 'ExoticAnimal'.
92+
addToZoo(manBeer);
93+
~~~~~~~
94+
!!! error TS2345: Argument of type '{ man: string; beer: string; }' is not assignable to parameter of type 'ExoticAnimal'.
95+
!!! error TS2345: Type '{ man: string; beer: string; }' is missing the following properties from type 'ManBearPig': bear, pig

tests/baselines/reference/errorsOnUnionsOfOverlappingObjects01.js

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,24 @@ declare function h(x: Foo | Bar | Other): any;
2828

2929
h(x);
3030
h({ a: '', b: '' })
31-
31+
32+
interface CatDog { cat: any, dog: any }
33+
interface ManBearPig { man: any, bear: any, pig: any }
34+
interface Platypus { platypus: any }
35+
36+
type ExoticAnimal =
37+
| CatDog
38+
| ManBearPig
39+
| Platypus;
40+
41+
declare function addToZoo(animal: ExoticAnimal): void;
42+
43+
addToZoo({ dog: "Barky McBarkface" });
44+
addToZoo({ man: "Manny", bear: "Coffee" });
45+
46+
const manBeer = { man: "Manny", beer: "Coffee" };
47+
addToZoo({ man: "Manny", beer: "Coffee" });
48+
addToZoo(manBeer);
3249

3350
//// [errorsOnUnionsOfOverlappingObjects01.js]
3451
"use strict";
@@ -41,3 +58,8 @@ g(exports.x);
4158
g({ a: '', b: '' });
4259
h(exports.x);
4360
h({ a: '', b: '' });
61+
addToZoo({ dog: "Barky McBarkface" });
62+
addToZoo({ man: "Manny", bear: "Coffee" });
63+
var manBeer = { man: "Manny", beer: "Coffee" };
64+
addToZoo({ man: "Manny", beer: "Coffee" });
65+
addToZoo(manBeer);

tests/baselines/reference/errorsOnUnionsOfOverlappingObjects01.symbols

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,58 @@ h({ a: '', b: '' })
7575
>a : Symbol(a, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 28, 3))
7676
>b : Symbol(b, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 28, 10))
7777

78+
interface CatDog { cat: any, dog: any }
79+
>CatDog : Symbol(CatDog, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 28, 19))
80+
>cat : Symbol(CatDog.cat, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 30, 18))
81+
>dog : Symbol(CatDog.dog, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 30, 28))
82+
83+
interface ManBearPig { man: any, bear: any, pig: any }
84+
>ManBearPig : Symbol(ManBearPig, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 30, 39))
85+
>man : Symbol(ManBearPig.man, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 31, 22))
86+
>bear : Symbol(ManBearPig.bear, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 31, 32))
87+
>pig : Symbol(ManBearPig.pig, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 31, 43))
88+
89+
interface Platypus { platypus: any }
90+
>Platypus : Symbol(Platypus, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 31, 54))
91+
>platypus : Symbol(Platypus.platypus, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 32, 20))
92+
93+
type ExoticAnimal =
94+
>ExoticAnimal : Symbol(ExoticAnimal, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 32, 36))
95+
96+
| CatDog
97+
>CatDog : Symbol(CatDog, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 28, 19))
98+
99+
| ManBearPig
100+
>ManBearPig : Symbol(ManBearPig, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 30, 39))
101+
102+
| Platypus;
103+
>Platypus : Symbol(Platypus, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 31, 54))
104+
105+
declare function addToZoo(animal: ExoticAnimal): void;
106+
>addToZoo : Symbol(addToZoo, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 37, 15))
107+
>animal : Symbol(animal, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 39, 26))
108+
>ExoticAnimal : Symbol(ExoticAnimal, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 32, 36))
109+
110+
addToZoo({ dog: "Barky McBarkface" });
111+
>addToZoo : Symbol(addToZoo, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 37, 15))
112+
>dog : Symbol(dog, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 41, 10))
113+
114+
addToZoo({ man: "Manny", bear: "Coffee" });
115+
>addToZoo : Symbol(addToZoo, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 37, 15))
116+
>man : Symbol(man, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 42, 10))
117+
>bear : Symbol(bear, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 42, 24))
118+
119+
const manBeer = { man: "Manny", beer: "Coffee" };
120+
>manBeer : Symbol(manBeer, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 44, 5))
121+
>man : Symbol(man, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 44, 17))
122+
>beer : Symbol(beer, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 44, 31))
123+
124+
addToZoo({ man: "Manny", beer: "Coffee" });
125+
>addToZoo : Symbol(addToZoo, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 37, 15))
126+
>man : Symbol(man, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 45, 10))
127+
>beer : Symbol(beer, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 45, 24))
128+
129+
addToZoo(manBeer);
130+
>addToZoo : Symbol(addToZoo, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 37, 15))
131+
>manBeer : Symbol(manBeer, Decl(errorsOnUnionsOfOverlappingObjects01.ts, 44, 5))
132+

tests/baselines/reference/errorsOnUnionsOfOverlappingObjects01.types

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,64 @@ h({ a: '', b: '' })
8080
>b : string
8181
>'' : ""
8282

83+
interface CatDog { cat: any, dog: any }
84+
>cat : any
85+
>dog : any
86+
87+
interface ManBearPig { man: any, bear: any, pig: any }
88+
>man : any
89+
>bear : any
90+
>pig : any
91+
92+
interface Platypus { platypus: any }
93+
>platypus : any
94+
95+
type ExoticAnimal =
96+
>ExoticAnimal : ExoticAnimal
97+
98+
| CatDog
99+
| ManBearPig
100+
| Platypus;
101+
102+
declare function addToZoo(animal: ExoticAnimal): void;
103+
>addToZoo : (animal: ExoticAnimal) => void
104+
>animal : ExoticAnimal
105+
106+
addToZoo({ dog: "Barky McBarkface" });
107+
>addToZoo({ dog: "Barky McBarkface" }) : void
108+
>addToZoo : (animal: ExoticAnimal) => void
109+
>{ dog: "Barky McBarkface" } : { dog: string; }
110+
>dog : string
111+
>"Barky McBarkface" : "Barky McBarkface"
112+
113+
addToZoo({ man: "Manny", bear: "Coffee" });
114+
>addToZoo({ man: "Manny", bear: "Coffee" }) : void
115+
>addToZoo : (animal: ExoticAnimal) => void
116+
>{ man: "Manny", bear: "Coffee" } : { man: string; bear: string; }
117+
>man : string
118+
>"Manny" : "Manny"
119+
>bear : string
120+
>"Coffee" : "Coffee"
121+
122+
const manBeer = { man: "Manny", beer: "Coffee" };
123+
>manBeer : { man: string; beer: string; }
124+
>{ man: "Manny", beer: "Coffee" } : { man: string; beer: string; }
125+
>man : string
126+
>"Manny" : "Manny"
127+
>beer : string
128+
>"Coffee" : "Coffee"
129+
130+
addToZoo({ man: "Manny", beer: "Coffee" });
131+
>addToZoo({ man: "Manny", beer: "Coffee" }) : void
132+
>addToZoo : (animal: ExoticAnimal) => void
133+
>{ man: "Manny", beer: "Coffee" } : { man: string; beer: string; }
134+
>man : string
135+
>"Manny" : "Manny"
136+
>beer : string
137+
>"Coffee" : "Coffee"
138+
139+
addToZoo(manBeer);
140+
>addToZoo(manBeer) : void
141+
>addToZoo : (animal: ExoticAnimal) => void
142+
>manBeer : { man: string; beer: string; }
143+

tests/baselines/reference/unionTypeWithRecursiveSubtypeReduction2.errors.txt

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@ tests/cases/compiler/unionTypeWithRecursiveSubtypeReduction2.ts(19,1): error TS2
55
tests/cases/compiler/unionTypeWithRecursiveSubtypeReduction2.ts(20,1): error TS2322: Type 'Class' is not assignable to type 'Property'.
66
Types of property 'parent' are incompatible.
77
Type 'Namespace' is not assignable to type 'Module | Class'.
8-
Property 'parent' is missing in type 'Namespace' but required in type 'Class'.
8+
Type 'Namespace' is not assignable to type 'Module'.
9+
Types of property 'members' are incompatible.
10+
Type '(Class | Property)[]' is not assignable to type 'Class[]'.
11+
Type 'Class | Property' is not assignable to type 'Class'.
12+
Type 'Property' is not assignable to type 'Class'.
913

1014

1115
==== tests/cases/compiler/unionTypeWithRecursiveSubtypeReduction2.ts (2 errors) ====
@@ -39,6 +43,9 @@ tests/cases/compiler/unionTypeWithRecursiveSubtypeReduction2.ts(20,1): error TS2
3943
!!! error TS2322: Type 'Class' is not assignable to type 'Property'.
4044
!!! error TS2322: Types of property 'parent' are incompatible.
4145
!!! error TS2322: Type 'Namespace' is not assignable to type 'Module | Class'.
42-
!!! error TS2322: Property 'parent' is missing in type 'Namespace' but required in type 'Class'.
43-
!!! related TS2728 tests/cases/compiler/unionTypeWithRecursiveSubtypeReduction2.ts:10:12: 'parent' is declared here.
46+
!!! error TS2322: Type 'Namespace' is not assignable to type 'Module'.
47+
!!! error TS2322: Types of property 'members' are incompatible.
48+
!!! error TS2322: Type '(Class | Property)[]' is not assignable to type 'Class[]'.
49+
!!! error TS2322: Type 'Class | Property' is not assignable to type 'Class'.
50+
!!! error TS2322: Type 'Property' is not assignable to type 'Class'.
4451

tests/cases/compiler/errorsOnUnionsOfOverlappingObjects01.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,21 @@ declare function h(x: Foo | Bar | Other): any;
2727

2828
h(x);
2929
h({ a: '', b: '' })
30+
31+
interface CatDog { cat: any, dog: any }
32+
interface ManBearPig { man: any, bear: any, pig: any }
33+
interface Platypus { platypus: any }
34+
35+
type ExoticAnimal =
36+
| CatDog
37+
| ManBearPig
38+
| Platypus;
39+
40+
declare function addToZoo(animal: ExoticAnimal): void;
41+
42+
addToZoo({ dog: "Barky McBarkface" });
43+
addToZoo({ man: "Manny", bear: "Coffee" });
44+
45+
const manBeer = { man: "Manny", beer: "Coffee" };
46+
addToZoo({ man: "Manny", beer: "Coffee" });
47+
addToZoo(manBeer);

0 commit comments

Comments
 (0)