Skip to content

Commit e9d136a

Browse files
committed
Limit to single overlappy type to improve back other errors
1 parent c605f6b commit e9d136a

11 files changed

+88
-21
lines changed

src/compiler/checker.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21985,7 +21985,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2198521985
}
2198621986
if (reportErrors) {
2198721987
// Elaborate only if we can find a best matching type in the target
21988-
const bestMatchingType = getBestMatchingType(source, target, isRelatedTo);
21988+
const bestMatchingType = getBestMatchingType(source, target, isRelatedTo, /*singleOverlappy*/ true);
2198921989
if (bestMatchingType) {
2199021990
isRelatedTo(source, bestMatchingType, RecursionFlags.Target, /*reportErrors*/ true, /*headMessage*/ undefined, intersectionState);
2199121991
}
@@ -23712,11 +23712,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2371223712
return getPropertiesOfType(type).filter(targetProp => containsMissingType(getTypeOfSymbol(targetProp)));
2371323713
}
2371423714

23715-
function getBestMatchingType(source: Type, target: UnionOrIntersectionType, isRelatedTo = compareTypesAssignable) {
23715+
function getBestMatchingType(source: Type, target: UnionOrIntersectionType, isRelatedTo = compareTypesAssignable, singleOverlappy = false) {
2371623716
return findMatchingDiscriminantType(source, target, isRelatedTo) ||
2371723717
findMatchingTypeReferenceOrTypeAliasReference(source, target) ||
2371823718
findBestTypeForInvokable(source, target) ||
23719-
findMostOverlappyType(source, filterTypesForObjectLiteralMatch(source, target));
23719+
findMostOverlappyType(source, filterTypesForObjectLiteralMatch(source, target), singleOverlappy);
2372023720
}
2372123721

2372223722
function discriminateTypeByDiscriminableItems(target: UnionType, discriminators: (readonly [() => Type, __String])[], related: (source: Type, target: Type) => boolean | Ternary) {
@@ -50924,7 +50924,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
5092450924
}
5092550925
}
5092650926

50927-
function findMostOverlappyType(source: Type, target: Type) {
50927+
function findMostOverlappyType(source: Type, target: Type, singleOverlappy: boolean) {
5092850928
if (!(target.flags & TypeFlags.UnionOrIntersection)) {
5092950929
return target;
5093050930
}
@@ -50954,7 +50954,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
5095450954
}
5095550955
}
5095650956
}
50957-
return bestMatches.length ? getUnionType(bestMatches) : undefined;
50957+
return bestMatches.length ? singleOverlappy ? bestMatches[0] : getUnionType(bestMatches) : undefined;
5095850958
}
5095950959

5096050960
function filterPrimitivesIfContainsNonPrimitive(type: UnionType) {

tests/baselines/reference/assignmentCompatWithDiscriminatedUnion.errors.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
assignmentCompatWithDiscriminatedUnion.ts(44,5): error TS2322: Type 'S' is not assignable to type 'T'.
22
Type 'S' is not assignable to type '{ a: 0; b: 4 | 1; } | { a: 1; b: 2 | 4; }'.
3+
Type 'S' is not assignable to type '{ a: 0; b: 4 | 1; }'.
4+
Types of property 'a' are incompatible.
5+
Type '0 | 2' is not assignable to type '0'.
6+
Type '2' is not assignable to type '0'.
37
assignmentCompatWithDiscriminatedUnion.ts(58,5): error TS2322: Type 'S' is not assignable to type 'T'.
48
Type 'S' is not assignable to type '{ a: 0; b: 4 | 1; } | { a: 2; b: 4 | 3; c: string; }'.
9+
Type 'S' is not assignable to type '{ a: 0; b: 4 | 1; }'.
10+
Types of property 'a' are incompatible.
11+
Type '0 | 2' is not assignable to type '0'.
12+
Type '2' is not assignable to type '0'.
513
assignmentCompatWithDiscriminatedUnion.ts(82,5): error TS2322: Type 'S' is not assignable to type 'T'.
614

715

@@ -53,6 +61,10 @@ assignmentCompatWithDiscriminatedUnion.ts(82,5): error TS2322: Type 'S' is not a
5361
~
5462
!!! error TS2322: Type 'S' is not assignable to type 'T'.
5563
!!! error TS2322: Type 'S' is not assignable to type '{ a: 0; b: 4 | 1; } | { a: 1; b: 2 | 4; }'.
64+
!!! error TS2322: Type 'S' is not assignable to type '{ a: 0; b: 4 | 1; }'.
65+
!!! error TS2322: Types of property 'a' are incompatible.
66+
!!! error TS2322: Type '0 | 2' is not assignable to type '0'.
67+
!!! error TS2322: Type '2' is not assignable to type '0'.
5668
}
5769

5870
// Unmatched non-discriminants
@@ -70,6 +82,10 @@ assignmentCompatWithDiscriminatedUnion.ts(82,5): error TS2322: Type 'S' is not a
7082
~
7183
!!! error TS2322: Type 'S' is not assignable to type 'T'.
7284
!!! error TS2322: Type 'S' is not assignable to type '{ a: 0; b: 4 | 1; } | { a: 2; b: 4 | 3; c: string; }'.
85+
!!! error TS2322: Type 'S' is not assignable to type '{ a: 0; b: 4 | 1; }'.
86+
!!! error TS2322: Types of property 'a' are incompatible.
87+
!!! error TS2322: Type '0 | 2' is not assignable to type '0'.
88+
!!! error TS2322: Type '2' is not assignable to type '0'.
7389
}
7490

7591
// Maximum discriminant combinations

tests/baselines/reference/bigintWithLib.errors.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ bigintWithLib.ts(19,33): error TS2769: No overload matches this call.
1111
Type 'number' is not assignable to type 'bigint'.
1212
Overload 3 of 3, '(buffer: ArrayBufferLike, byteOffset?: number, length?: number): BigInt64Array', gave the following error.
1313
Argument of type 'number[]' is not assignable to parameter of type 'ArrayBufferLike'.
14-
Type 'number[]' is not assignable to type 'ArrayBuffer | SharedArrayBuffer'.
14+
Type 'number[]' is missing the following properties from type 'ArrayBuffer': byteLength, [Symbol.toStringTag]
1515
bigintWithLib.ts(24,13): error TS2540: Cannot assign to 'length' because it is a read-only property.
1616
bigintWithLib.ts(31,35): error TS2769: No overload matches this call.
1717
Overload 1 of 3, '(length?: number): BigUint64Array', gave the following error.
@@ -60,7 +60,7 @@ bigintWithLib.ts(46,26): error TS2345: Argument of type 'number' is not assignab
6060
!!! error TS2769: Type 'number' is not assignable to type 'bigint'.
6161
!!! error TS2769: Overload 3 of 3, '(buffer: ArrayBufferLike, byteOffset?: number, length?: number): BigInt64Array', gave the following error.
6262
!!! error TS2769: Argument of type 'number[]' is not assignable to parameter of type 'ArrayBufferLike'.
63-
!!! error TS2769: Type 'number[]' is not assignable to type 'ArrayBuffer | SharedArrayBuffer'.
63+
!!! error TS2769: Type 'number[]' is missing the following properties from type 'ArrayBuffer': byteLength, [Symbol.toStringTag]
6464
bigIntArray = new BigInt64Array(new ArrayBuffer(80));
6565
bigIntArray = new BigInt64Array(new ArrayBuffer(80), 8);
6666
bigIntArray = new BigInt64Array(new ArrayBuffer(80), 8, 3);

tests/baselines/reference/contextualTypeWithUnionTypeObjectLiteral.errors.txt

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
contextualTypeWithUnionTypeObjectLiteral.ts(14,5): error TS2322: Type '{ prop: string | number; }' is not assignable to type '{ prop: string; } | { prop: number; }'.
2-
Type '{ prop: string | number; }' is not assignable to type '{ prop: string; } | { prop: number; }'.
2+
Type '{ prop: string | number; }' is not assignable to type '{ prop: string; }'.
3+
Types of property 'prop' are incompatible.
4+
Type 'string | number' is not assignable to type 'string'.
5+
Type 'number' is not assignable to type 'string'.
36
contextualTypeWithUnionTypeObjectLiteral.ts(20,5): error TS2322: Type '{ prop: string | number; }' is not assignable to type '{ prop: string; anotherP: string; } | { prop: number; }'.
4-
Type '{ prop: string | number; }' is not assignable to type '{ prop: string; anotherP: string; } | { prop: number; }'.
7+
Property 'anotherP' is missing in type '{ prop: string | number; }' but required in type '{ prop: string; anotherP: string; }'.
58
contextualTypeWithUnionTypeObjectLiteral.ts(22,5): error TS2322: Type 'string | number' is not assignable to type 'string'.
69
Type 'number' is not assignable to type 'string'.
710
contextualTypeWithUnionTypeObjectLiteral.ts(26,5): error TS2322: Type 'string | number' is not assignable to type 'string'.
811
Type 'number' is not assignable to type 'string'.
912
contextualTypeWithUnionTypeObjectLiteral.ts(29,5): error TS2322: Type '{ prop: string | number; anotherP: string; anotherP1: number; }' is not assignable to type '{ prop: string; anotherP: string; } | { prop: number; anotherP1: number; }'.
10-
Type '{ prop: string | number; anotherP: string; anotherP1: number; }' is not assignable to type '{ prop: string; anotherP: string; } | { prop: number; anotherP1: number; }'.
13+
Type '{ prop: string | number; anotherP: string; anotherP1: number; }' is not assignable to type '{ prop: string; anotherP: string; }'.
14+
Types of property 'prop' are incompatible.
15+
Type 'string | number' is not assignable to type 'string'.
16+
Type 'number' is not assignable to type 'string'.
1117
contextualTypeWithUnionTypeObjectLiteral.ts(58,5): error TS2322: Type '(a: string, b: number) => string | number' is not assignable to type '((a: string, b: number) => string) | ((a: string, b: number) => number)'.
1218
Type '(a: string, b: number) => string | number' is not assignable to type '(a: string, b: number) => string'.
1319
Type 'string | number' is not assignable to type 'string'.
@@ -31,7 +37,10 @@ contextualTypeWithUnionTypeObjectLiteral.ts(58,5): error TS2322: Type '(a: strin
3137
var objStrOrNum3: { prop: string } | { prop: number } = {
3238
~~~~~~~~~~~~
3339
!!! error TS2322: Type '{ prop: string | number; }' is not assignable to type '{ prop: string; } | { prop: number; }'.
34-
!!! error TS2322: Type '{ prop: string | number; }' is not assignable to type '{ prop: string; } | { prop: number; }'.
40+
!!! error TS2322: Type '{ prop: string | number; }' is not assignable to type '{ prop: string; }'.
41+
!!! error TS2322: Types of property 'prop' are incompatible.
42+
!!! error TS2322: Type 'string | number' is not assignable to type 'string'.
43+
!!! error TS2322: Type 'number' is not assignable to type 'string'.
3544
prop: strOrNumber
3645
};
3746
var objStrOrNum4: { prop: string | number } = {
@@ -40,7 +49,8 @@ contextualTypeWithUnionTypeObjectLiteral.ts(58,5): error TS2322: Type '(a: strin
4049
var objStrOrNum5: { prop: string; anotherP: string; } | { prop: number } = { prop: strOrNumber };
4150
~~~~~~~~~~~~
4251
!!! error TS2322: Type '{ prop: string | number; }' is not assignable to type '{ prop: string; anotherP: string; } | { prop: number; }'.
43-
!!! error TS2322: Type '{ prop: string | number; }' is not assignable to type '{ prop: string; anotherP: string; } | { prop: number; }'.
52+
!!! error TS2322: Property 'anotherP' is missing in type '{ prop: string | number; }' but required in type '{ prop: string; anotherP: string; }'.
53+
!!! related TS2728 contextualTypeWithUnionTypeObjectLiteral.ts:20:35: 'anotherP' is declared here.
4454
var objStrOrNum6: { prop: string; anotherP: string; } | { prop: number } = {
4555
prop: strOrNumber,
4656
~~~~
@@ -60,7 +70,10 @@ contextualTypeWithUnionTypeObjectLiteral.ts(58,5): error TS2322: Type '(a: strin
6070
var objStrOrNum8: { prop: string; anotherP: string; } | { prop: number; anotherP1: number } = {
6171
~~~~~~~~~~~~
6272
!!! error TS2322: Type '{ prop: string | number; anotherP: string; anotherP1: number; }' is not assignable to type '{ prop: string; anotherP: string; } | { prop: number; anotherP1: number; }'.
63-
!!! error TS2322: Type '{ prop: string | number; anotherP: string; anotherP1: number; }' is not assignable to type '{ prop: string; anotherP: string; } | { prop: number; anotherP1: number; }'.
73+
!!! error TS2322: Type '{ prop: string | number; anotherP: string; anotherP1: number; }' is not assignable to type '{ prop: string; anotherP: string; }'.
74+
!!! error TS2322: Types of property 'prop' are incompatible.
75+
!!! error TS2322: Type 'string | number' is not assignable to type 'string'.
76+
!!! error TS2322: Type 'number' is not assignable to type 'string'.
6477
prop: strOrNumber,
6578
anotherP: str,
6679
anotherP1: num

tests/baselines/reference/excessPropertyCheckWithUnions.errors.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ excessPropertyCheckWithUnions.ts(33,28): error TS2353: Object literal may only s
66
excessPropertyCheckWithUnions.ts(34,26): error TS2353: Object literal may only specify known properties, and 'extra' does not exist in type '{ tag: "A"; x: string; } | { tag: "A"; y: number; }'.
77
excessPropertyCheckWithUnions.ts(37,1): error TS2322: Type '{ tag: "A"; }' is not assignable to type 'Ambiguous'.
88
Type '{ tag: "A"; }' is not assignable to type '{ tag: "A"; x: string; } | { tag: "A"; y: number; }'.
9+
Property 'x' is missing in type '{ tag: "A"; }' but required in type '{ tag: "A"; x: string; }'.
910
excessPropertyCheckWithUnions.ts(38,19): error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ tag: "A"; x: string; } | { tag: "A"; y: number; }'.
1011
excessPropertyCheckWithUnions.ts(47,35): error TS2353: Object literal may only specify known properties, and 'second' does not exist in type '{ a: 1; b: 1; first: string; }'.
1112
excessPropertyCheckWithUnions.ts(48,35): error TS2353: Object literal may only specify known properties, and 'third' does not exist in type '{ a: 1; b: 1; first: string; }'.
@@ -69,6 +70,8 @@ excessPropertyCheckWithUnions.ts(112,63): error TS2322: Type 'string' is not ass
6970
~~~
7071
!!! error TS2322: Type '{ tag: "A"; }' is not assignable to type 'Ambiguous'.
7172
!!! error TS2322: Type '{ tag: "A"; }' is not assignable to type '{ tag: "A"; x: string; } | { tag: "A"; y: number; }'.
73+
!!! error TS2322: Property 'x' is missing in type '{ tag: "A"; }' but required in type '{ tag: "A"; x: string; }'.
74+
!!! related TS2728 excessPropertyCheckWithUnions.ts:16:5: 'x' is declared here.
7275
amb = { tag: "A", z: true }
7376
~
7477
!!! error TS2353: Object literal may only specify known properties, and 'z' does not exist in type '{ tag: "A"; x: string; } | { tag: "A"; y: number; }'.

tests/baselines/reference/genericRestParameters3.errors.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ genericRestParameters3.ts(17,11): error TS2345: Argument of type '[10]' is not a
22
Type '[10]' is not assignable to type '[string]'.
33
Type 'number' is not assignable to type 'string'.
44
genericRestParameters3.ts(18,1): error TS2345: Argument of type '[]' is not assignable to parameter of type '[string] | [number, boolean]'.
5+
Type '[]' is not assignable to type '[string]'.
6+
Source has 0 element(s) but target requires 1.
57
genericRestParameters3.ts(23,1): error TS2322: Type '(x: string, y: string) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'.
68
Types of parameters 'y' and 'args' are incompatible.
79
Type '[string] | [number, boolean]' is not assignable to type '[y: string]'.
@@ -57,6 +59,8 @@ genericRestParameters3.ts(59,5): error TS2345: Argument of type '["what"]' is no
5759
f1("foo"); // Error
5860
~~~~~~~~~
5961
!!! error TS2345: Argument of type '[]' is not assignable to parameter of type '[string] | [number, boolean]'.
62+
!!! error TS2345: Type '[]' is not assignable to type '[string]'.
63+
!!! error TS2345: Source has 0 element(s) but target requires 1.
6064

6165
f2 = f1;
6266
f3 = f1;

tests/baselines/reference/intersectionAndUnionTypes.errors.txt

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,19 @@ intersectionAndUnionTypes.ts(28,1): error TS2322: Type '(A & B) | (C & D)' is no
2020
intersectionAndUnionTypes.ts(29,1): error TS2322: Type '(A & B) | (C & D)' is not assignable to type 'C | D'.
2121
Type 'A & B' is not assignable to type 'C | D'.
2222
intersectionAndUnionTypes.ts(31,1): error TS2322: Type 'A & B' is not assignable to type '(A | B) & (C | D)'.
23-
Type 'A & B' is not assignable to type '(A & C) | (A & D) | (B & C) | (B & D)'.
23+
Type 'A & B' is not assignable to type 'A & C'.
24+
Type 'A & B' is not assignable to type 'C'.
2425
intersectionAndUnionTypes.ts(32,1): error TS2322: Type 'A | B' is not assignable to type '(A | B) & (C | D)'.
2526
Type 'A' is not assignable to type '(A | B) & (C | D)'.
26-
Type 'A' is not assignable to type '(A & C) | (A & D)'.
27+
Type 'A' is not assignable to type 'A & C'.
28+
Property 'c' is missing in type 'A' but required in type 'C'.
2729
intersectionAndUnionTypes.ts(33,1): error TS2322: Type 'C & D' is not assignable to type '(A | B) & (C | D)'.
28-
Type 'C & D' is not assignable to type '(A & C) | (A & D) | (B & C) | (B & D)'.
30+
Type 'C & D' is not assignable to type 'A & C'.
31+
Type 'C & D' is not assignable to type 'A'.
2932
intersectionAndUnionTypes.ts(34,1): error TS2322: Type 'C | D' is not assignable to type '(A | B) & (C | D)'.
3033
Type 'C' is not assignable to type '(A | B) & (C | D)'.
31-
Type 'C' is not assignable to type '(A & C) | (B & C)'.
34+
Type 'C' is not assignable to type 'A & C'.
35+
Property 'a' is missing in type 'C' but required in type 'A'.
3236
intersectionAndUnionTypes.ts(35,1): error TS2322: Type '(A | B) & (C | D)' is not assignable to type 'A & B'.
3337
Type 'A & C' is not assignable to type 'A & B'.
3438
Property 'b' is missing in type 'A & C' but required in type 'B'.
@@ -105,21 +109,27 @@ intersectionAndUnionTypes.ts(37,1): error TS2322: Type '(A | B) & (C | D)' is no
105109
y = anb;
106110
~
107111
!!! error TS2322: Type 'A & B' is not assignable to type '(A | B) & (C | D)'.
108-
!!! error TS2322: Type 'A & B' is not assignable to type '(A & C) | (A & D) | (B & C) | (B & D)'.
112+
!!! error TS2322: Type 'A & B' is not assignable to type 'A & C'.
113+
!!! error TS2322: Type 'A & B' is not assignable to type 'C'.
109114
y = aob;
110115
~
111116
!!! error TS2322: Type 'A | B' is not assignable to type '(A | B) & (C | D)'.
112117
!!! error TS2322: Type 'A' is not assignable to type '(A | B) & (C | D)'.
113-
!!! error TS2322: Type 'A' is not assignable to type '(A & C) | (A & D)'.
118+
!!! error TS2322: Type 'A' is not assignable to type 'A & C'.
119+
!!! error TS2322: Property 'c' is missing in type 'A' but required in type 'C'.
120+
!!! related TS2728 intersectionAndUnionTypes.ts:3:15: 'c' is declared here.
114121
y = cnd;
115122
~
116123
!!! error TS2322: Type 'C & D' is not assignable to type '(A | B) & (C | D)'.
117-
!!! error TS2322: Type 'C & D' is not assignable to type '(A & C) | (A & D) | (B & C) | (B & D)'.
124+
!!! error TS2322: Type 'C & D' is not assignable to type 'A & C'.
125+
!!! error TS2322: Type 'C & D' is not assignable to type 'A'.
118126
y = cod;
119127
~
120128
!!! error TS2322: Type 'C | D' is not assignable to type '(A | B) & (C | D)'.
121129
!!! error TS2322: Type 'C' is not assignable to type '(A | B) & (C | D)'.
122-
!!! error TS2322: Type 'C' is not assignable to type '(A & C) | (B & C)'.
130+
!!! error TS2322: Type 'C' is not assignable to type 'A & C'.
131+
!!! error TS2322: Property 'a' is missing in type 'C' but required in type 'A'.
132+
!!! related TS2728 intersectionAndUnionTypes.ts:1:15: 'a' is declared here.
123133
anb = y;
124134
~~~
125135
!!! error TS2322: Type '(A | B) & (C | D)' is not assignable to type 'A & B'.

tests/baselines/reference/jsxComponentTypeErrors.errors.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ jsxComponentTypeErrors.tsx(28,16): error TS2786: 'MixedComponent' cannot be used
1818
Its element type 'ClassComponent | { type: string | undefined; }' is not a valid JSX element.
1919
Type 'ClassComponent' is not assignable to type 'Element | ElementClass | null'.
2020
Type 'ClassComponent' is not assignable to type 'Element | ElementClass'.
21+
Type 'ClassComponent' is not assignable to type 'Element'.
22+
Types of property 'type' are incompatible.
23+
Type 'string' is not assignable to type '"element"'.
2124
jsxComponentTypeErrors.tsx(37,16): error TS2786: 'obj.MemberFunctionComponent' cannot be used as a JSX component.
2225
Its return type '{}' is not a valid JSX element.
2326
Property 'type' is missing in type '{}' but required in type 'Element'.
@@ -80,6 +83,9 @@ jsxComponentTypeErrors.tsx(38,16): error TS2786: 'obj. MemberClassComponent' can
8083
!!! error TS2786: Its element type 'ClassComponent | { type: string | undefined; }' is not a valid JSX element.
8184
!!! error TS2786: Type 'ClassComponent' is not assignable to type 'Element | ElementClass | null'.
8285
!!! error TS2786: Type 'ClassComponent' is not assignable to type 'Element | ElementClass'.
86+
!!! error TS2786: Type 'ClassComponent' is not assignable to type 'Element'.
87+
!!! error TS2786: Types of property 'type' are incompatible.
88+
!!! error TS2786: Type 'string' is not assignable to type '"element"'.
8389

8490
const obj = {
8591
MemberFunctionComponent() {

0 commit comments

Comments
 (0)