Skip to content

Commit 53809d8

Browse files
authored
Remove unnecessary check for misaligned complex rest parameters (#47934)
* Remove unnecessary check for misaligned complex rest parameters * Add tests
1 parent 1c06ef3 commit 53809d8

File tree

6 files changed

+186
-23
lines changed

6 files changed

+186
-23
lines changed

src/compiler/checker.ts

-4
Original file line numberDiff line numberDiff line change
@@ -17671,10 +17671,6 @@ namespace ts {
1767117671
if (sourceRestType || targetRestType) {
1767217672
void instantiateType(sourceRestType || targetRestType, reportUnreliableMarkers);
1767317673
}
17674-
if (sourceRestType && targetRestType && sourceCount !== targetCount) {
17675-
// We're not able to relate misaligned complex rest parameters
17676-
return Ternary.False;
17677-
}
1767817674

1767917675
const kind = target.declaration ? target.declaration.kind : SyntaxKind.Unknown;
1768017676
const strictVariance = !(checkMode & SignatureCheckMode.Callback) && strictFunctionTypes && kind !== SyntaxKind.MethodDeclaration &&

tests/baselines/reference/genericRestParameters3.errors.txt

+22-9
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ tests/cases/conformance/types/rest/genericRestParameters3.ts(17,11): error TS234
44
tests/cases/conformance/types/rest/genericRestParameters3.ts(18,1): error TS2345: Argument of type '[]' is not assignable to parameter of type '[string] | [number, boolean]'.
55
Type '[]' is not assignable to type '[number, boolean]'.
66
Source has 0 element(s) but target requires 2.
7-
tests/cases/conformance/types/rest/genericRestParameters3.ts(22,1): error TS2322: Type '(x: string, ...args: [string] | [number, boolean]) => void' is not assignable to type '(...args: [string, string] | [string, number, boolean]) => void'.
87
tests/cases/conformance/types/rest/genericRestParameters3.ts(23,1): error TS2322: Type '(x: string, y: string) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'.
98
Types of parameters 'y' and 'args' are incompatible.
109
Type '[string] | [number, boolean]' is not assignable to type '[y: string]'.
@@ -15,7 +14,6 @@ tests/cases/conformance/types/rest/genericRestParameters3.ts(24,1): error TS2322
1514
Type '[string] | [number, boolean]' is not assignable to type '[y: number, z: boolean]'.
1615
Type '[string]' is not assignable to type '[y: number, z: boolean]'.
1716
Source has 1 element(s) but target requires 2.
18-
tests/cases/conformance/types/rest/genericRestParameters3.ts(25,1): error TS2322: Type '(...args: [string, string] | [string, number, boolean]) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'.
1917
tests/cases/conformance/types/rest/genericRestParameters3.ts(35,1): error TS2554: Expected 1 arguments, but got 0.
2018
tests/cases/conformance/types/rest/genericRestParameters3.ts(36,21): error TS2345: Argument of type 'number' is not assignable to parameter of type '(...args: CoolArray<any>) => void'.
2119
tests/cases/conformance/types/rest/genericRestParameters3.ts(37,21): error TS2345: Argument of type '<T extends any[]>(cb: (...args: T) => void) => void' is not assignable to parameter of type '(...args: CoolArray<any>) => void'.
@@ -36,7 +34,7 @@ tests/cases/conformance/types/rest/genericRestParameters3.ts(59,5): error TS2345
3634
Source has 1 element(s) but target requires 2.
3735

3836

39-
==== tests/cases/conformance/types/rest/genericRestParameters3.ts (15 errors) ====
37+
==== tests/cases/conformance/types/rest/genericRestParameters3.ts (13 errors) ====
4038
declare let f1: (x: string, ...args: [string] | [number, boolean]) => void;
4139
declare let f2: (x: string, y: string) => void;
4240
declare let f3: (x: string, y: number, z: boolean) => void;
@@ -66,9 +64,7 @@ tests/cases/conformance/types/rest/genericRestParameters3.ts(59,5): error TS2345
6664

6765
f2 = f1;
6866
f3 = f1;
69-
f4 = f1; // Error, misaligned complex rest types
70-
~~
71-
!!! error TS2322: Type '(x: string, ...args: [string] | [number, boolean]) => void' is not assignable to type '(...args: [string, string] | [string, number, boolean]) => void'.
67+
f4 = f1;
7268
f1 = f2; // Error
7369
~~
7470
!!! error TS2322: Type '(x: string, y: string) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'.
@@ -83,9 +79,7 @@ tests/cases/conformance/types/rest/genericRestParameters3.ts(59,5): error TS2345
8379
!!! error TS2322: Type '[string] | [number, boolean]' is not assignable to type '[y: number, z: boolean]'.
8480
!!! error TS2322: Type '[string]' is not assignable to type '[y: number, z: boolean]'.
8581
!!! error TS2322: Source has 1 element(s) but target requires 2.
86-
f1 = f4; // Error, misaligned complex rest types
87-
~~
88-
!!! error TS2322: Type '(...args: [string, string] | [string, number, boolean]) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'.
82+
f1 = f4;
8983

9084
// Repro from #26110
9185

@@ -159,4 +153,23 @@ tests/cases/conformance/types/rest/genericRestParameters3.ts(59,5): error TS2345
159153
declare function foo2(...args: string[] | number[]): void;
160154
let x2: ReadonlyArray<string> = ["hello"];
161155
foo2(...x2);
156+
157+
// Repros from #47754
158+
159+
type RestParams = [y: string] | [y: number];
160+
161+
type Signature = (x: string, ...rest: RestParams) => void;
162+
163+
type MergedParams = Parameters<Signature>; // [x: string, y: string] | [x: string, y: number]
164+
165+
declare let ff1: (...rest: [string, string] | [string, number]) => void;
166+
declare let ff2: (x: string, ...rest: [string] | [number]) => void;
167+
168+
ff1 = ff2;
169+
ff2 = ff1;
170+
171+
function ff3<A extends unknown[]>(s1: (...args: [x: string, ...rest: A | [number]]) => void, s2: (x: string, ...rest: A | [number]) => void) {
172+
s1 = s2;
173+
s2 = s1;
174+
}
162175

tests/baselines/reference/genericRestParameters3.js

+35-4
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ f1("foo"); // Error
2020

2121
f2 = f1;
2222
f3 = f1;
23-
f4 = f1; // Error, misaligned complex rest types
23+
f4 = f1;
2424
f1 = f2; // Error
2525
f1 = f3; // Error
26-
f1 = f4; // Error, misaligned complex rest types
26+
f1 = f4;
2727

2828
// Repro from #26110
2929

@@ -64,6 +64,25 @@ hmm("what"); // no error? A = [] | [number, string] ?
6464
declare function foo2(...args: string[] | number[]): void;
6565
let x2: ReadonlyArray<string> = ["hello"];
6666
foo2(...x2);
67+
68+
// Repros from #47754
69+
70+
type RestParams = [y: string] | [y: number];
71+
72+
type Signature = (x: string, ...rest: RestParams) => void;
73+
74+
type MergedParams = Parameters<Signature>; // [x: string, y: string] | [x: string, y: number]
75+
76+
declare let ff1: (...rest: [string, string] | [string, number]) => void;
77+
declare let ff2: (x: string, ...rest: [string] | [number]) => void;
78+
79+
ff1 = ff2;
80+
ff2 = ff1;
81+
82+
function ff3<A extends unknown[]>(s1: (...args: [x: string, ...rest: A | [number]]) => void, s2: (x: string, ...rest: A | [number]) => void) {
83+
s1 = s2;
84+
s2 = s1;
85+
}
6786

6887

6988
//// [genericRestParameters3.js]
@@ -87,10 +106,10 @@ f1("foo", 10); // Error
87106
f1("foo"); // Error
88107
f2 = f1;
89108
f3 = f1;
90-
f4 = f1; // Error, misaligned complex rest types
109+
f4 = f1;
91110
f1 = f2; // Error
92111
f1 = f3; // Error
93-
f1 = f4; // Error, misaligned complex rest types
112+
f1 = f4;
94113
foo(); // Error
95114
foo(100); // Error
96115
foo(foo); // Error
@@ -112,6 +131,12 @@ hmm(1, "s"); // okay, A = [1, "s"]
112131
hmm("what"); // no error? A = [] | [number, string] ?
113132
var x2 = ["hello"];
114133
foo2.apply(void 0, x2);
134+
ff1 = ff2;
135+
ff2 = ff1;
136+
function ff3(s1, s2) {
137+
s1 = s2;
138+
s2 = s1;
139+
}
115140

116141

117142
//// [genericRestParameters3.d.ts]
@@ -135,3 +160,9 @@ declare const ca: CoolArray<number>;
135160
declare function hmm<A extends [] | [number, string]>(...args: A): void;
136161
declare function foo2(...args: string[] | number[]): void;
137162
declare let x2: ReadonlyArray<string>;
163+
declare type RestParams = [y: string] | [y: number];
164+
declare type Signature = (x: string, ...rest: RestParams) => void;
165+
declare type MergedParams = Parameters<Signature>;
166+
declare let ff1: (...rest: [string, string] | [string, number]) => void;
167+
declare let ff2: (x: string, ...rest: [string] | [number]) => void;
168+
declare function ff3<A extends unknown[]>(s1: (...args: [x: string, ...rest: A | [number]]) => void, s2: (x: string, ...rest: A | [number]) => void): void;

tests/baselines/reference/genericRestParameters3.symbols

+55-2
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ f3 = f1;
6767
>f3 : Symbol(f3, Decl(genericRestParameters3.ts, 2, 11))
6868
>f1 : Symbol(f1, Decl(genericRestParameters3.ts, 0, 11))
6969

70-
f4 = f1; // Error, misaligned complex rest types
70+
f4 = f1;
7171
>f4 : Symbol(f4, Decl(genericRestParameters3.ts, 3, 11))
7272
>f1 : Symbol(f1, Decl(genericRestParameters3.ts, 0, 11))
7373

@@ -79,7 +79,7 @@ f1 = f3; // Error
7979
>f1 : Symbol(f1, Decl(genericRestParameters3.ts, 0, 11))
8080
>f3 : Symbol(f3, Decl(genericRestParameters3.ts, 2, 11))
8181

82-
f1 = f4; // Error, misaligned complex rest types
82+
f1 = f4;
8383
>f1 : Symbol(f1, Decl(genericRestParameters3.ts, 0, 11))
8484
>f4 : Symbol(f4, Decl(genericRestParameters3.ts, 3, 11))
8585

@@ -190,3 +190,56 @@ foo2(...x2);
190190
>foo2 : Symbol(foo2, Decl(genericRestParameters3.ts, 58, 12))
191191
>x2 : Symbol(x2, Decl(genericRestParameters3.ts, 63, 3))
192192

193+
// Repros from #47754
194+
195+
type RestParams = [y: string] | [y: number];
196+
>RestParams : Symbol(RestParams, Decl(genericRestParameters3.ts, 64, 12))
197+
198+
type Signature = (x: string, ...rest: RestParams) => void;
199+
>Signature : Symbol(Signature, Decl(genericRestParameters3.ts, 68, 44))
200+
>x : Symbol(x, Decl(genericRestParameters3.ts, 70, 18))
201+
>rest : Symbol(rest, Decl(genericRestParameters3.ts, 70, 28))
202+
>RestParams : Symbol(RestParams, Decl(genericRestParameters3.ts, 64, 12))
203+
204+
type MergedParams = Parameters<Signature>; // [x: string, y: string] | [x: string, y: number]
205+
>MergedParams : Symbol(MergedParams, Decl(genericRestParameters3.ts, 70, 58))
206+
>Parameters : Symbol(Parameters, Decl(lib.es5.d.ts, --, --))
207+
>Signature : Symbol(Signature, Decl(genericRestParameters3.ts, 68, 44))
208+
209+
declare let ff1: (...rest: [string, string] | [string, number]) => void;
210+
>ff1 : Symbol(ff1, Decl(genericRestParameters3.ts, 74, 11))
211+
>rest : Symbol(rest, Decl(genericRestParameters3.ts, 74, 18))
212+
213+
declare let ff2: (x: string, ...rest: [string] | [number]) => void;
214+
>ff2 : Symbol(ff2, Decl(genericRestParameters3.ts, 75, 11))
215+
>x : Symbol(x, Decl(genericRestParameters3.ts, 75, 18))
216+
>rest : Symbol(rest, Decl(genericRestParameters3.ts, 75, 28))
217+
218+
ff1 = ff2;
219+
>ff1 : Symbol(ff1, Decl(genericRestParameters3.ts, 74, 11))
220+
>ff2 : Symbol(ff2, Decl(genericRestParameters3.ts, 75, 11))
221+
222+
ff2 = ff1;
223+
>ff2 : Symbol(ff2, Decl(genericRestParameters3.ts, 75, 11))
224+
>ff1 : Symbol(ff1, Decl(genericRestParameters3.ts, 74, 11))
225+
226+
function ff3<A extends unknown[]>(s1: (...args: [x: string, ...rest: A | [number]]) => void, s2: (x: string, ...rest: A | [number]) => void) {
227+
>ff3 : Symbol(ff3, Decl(genericRestParameters3.ts, 78, 10))
228+
>A : Symbol(A, Decl(genericRestParameters3.ts, 80, 13))
229+
>s1 : Symbol(s1, Decl(genericRestParameters3.ts, 80, 34))
230+
>args : Symbol(args, Decl(genericRestParameters3.ts, 80, 39))
231+
>A : Symbol(A, Decl(genericRestParameters3.ts, 80, 13))
232+
>s2 : Symbol(s2, Decl(genericRestParameters3.ts, 80, 92))
233+
>x : Symbol(x, Decl(genericRestParameters3.ts, 80, 98))
234+
>rest : Symbol(rest, Decl(genericRestParameters3.ts, 80, 108))
235+
>A : Symbol(A, Decl(genericRestParameters3.ts, 80, 13))
236+
237+
s1 = s2;
238+
>s1 : Symbol(s1, Decl(genericRestParameters3.ts, 80, 34))
239+
>s2 : Symbol(s2, Decl(genericRestParameters3.ts, 80, 92))
240+
241+
s2 = s1;
242+
>s2 : Symbol(s2, Decl(genericRestParameters3.ts, 80, 92))
243+
>s1 : Symbol(s1, Decl(genericRestParameters3.ts, 80, 34))
244+
}
245+

tests/baselines/reference/genericRestParameters3.types

+53-2
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ f3 = f1;
9393
>f3 : (x: string, y: number, z: boolean) => void
9494
>f1 : (x: string, ...args: [string] | [number, boolean]) => void
9595

96-
f4 = f1; // Error, misaligned complex rest types
96+
f4 = f1;
9797
>f4 = f1 : (x: string, ...args: [string] | [number, boolean]) => void
9898
>f4 : (...args: [string, string] | [string, number, boolean]) => void
9999
>f1 : (x: string, ...args: [string] | [number, boolean]) => void
@@ -108,7 +108,7 @@ f1 = f3; // Error
108108
>f1 : (x: string, ...args: [string] | [number, boolean]) => void
109109
>f3 : (x: string, y: number, z: boolean) => void
110110

111-
f1 = f4; // Error, misaligned complex rest types
111+
f1 = f4;
112112
>f1 = f4 : (...args: [string, string] | [string, number, boolean]) => void
113113
>f1 : (x: string, ...args: [string] | [number, boolean]) => void
114114
>f4 : (...args: [string, string] | [string, number, boolean]) => void
@@ -227,3 +227,54 @@ foo2(...x2);
227227
>...x2 : string
228228
>x2 : readonly string[]
229229

230+
// Repros from #47754
231+
232+
type RestParams = [y: string] | [y: number];
233+
>RestParams : RestParams
234+
235+
type Signature = (x: string, ...rest: RestParams) => void;
236+
>Signature : Signature
237+
>x : string
238+
>rest : RestParams
239+
240+
type MergedParams = Parameters<Signature>; // [x: string, y: string] | [x: string, y: number]
241+
>MergedParams : [x: string, y: string] | [x: string, y: number]
242+
243+
declare let ff1: (...rest: [string, string] | [string, number]) => void;
244+
>ff1 : (...rest: [string, string] | [string, number]) => void
245+
>rest : [string, string] | [string, number]
246+
247+
declare let ff2: (x: string, ...rest: [string] | [number]) => void;
248+
>ff2 : (x: string, ...rest: [string] | [number]) => void
249+
>x : string
250+
>rest : [string] | [number]
251+
252+
ff1 = ff2;
253+
>ff1 = ff2 : (x: string, ...rest: [string] | [number]) => void
254+
>ff1 : (...rest: [string, string] | [string, number]) => void
255+
>ff2 : (x: string, ...rest: [string] | [number]) => void
256+
257+
ff2 = ff1;
258+
>ff2 = ff1 : (...rest: [string, string] | [string, number]) => void
259+
>ff2 : (x: string, ...rest: [string] | [number]) => void
260+
>ff1 : (...rest: [string, string] | [string, number]) => void
261+
262+
function ff3<A extends unknown[]>(s1: (...args: [x: string, ...rest: A | [number]]) => void, s2: (x: string, ...rest: A | [number]) => void) {
263+
>ff3 : <A extends unknown[]>(s1: (...args: [x: string, ...rest: A | [number]]) => void, s2: (x: string, ...rest: A | [number]) => void) => void
264+
>s1 : (...args: [x: string, ...rest: A | [number]]) => void
265+
>args : [string, number] | [x: string, ...rest: A]
266+
>s2 : (x: string, ...rest: A | [number]) => void
267+
>x : string
268+
>rest : [number] | A
269+
270+
s1 = s2;
271+
>s1 = s2 : (x: string, ...rest: [number] | A) => void
272+
>s1 : (...args: [string, number] | [x: string, ...rest: A]) => void
273+
>s2 : (x: string, ...rest: [number] | A) => void
274+
275+
s2 = s1;
276+
>s2 = s1 : (...args: [string, number] | [x: string, ...rest: A]) => void
277+
>s2 : (x: string, ...rest: [number] | A) => void
278+
>s1 : (...args: [string, number] | [x: string, ...rest: A]) => void
279+
}
280+

tests/cases/conformance/types/rest/genericRestParameters3.ts

+21-2
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ f1("foo"); // Error
2222

2323
f2 = f1;
2424
f3 = f1;
25-
f4 = f1; // Error, misaligned complex rest types
25+
f4 = f1;
2626
f1 = f2; // Error
2727
f1 = f3; // Error
28-
f1 = f4; // Error, misaligned complex rest types
28+
f1 = f4;
2929

3030
// Repro from #26110
3131

@@ -66,3 +66,22 @@ hmm("what"); // no error? A = [] | [number, string] ?
6666
declare function foo2(...args: string[] | number[]): void;
6767
let x2: ReadonlyArray<string> = ["hello"];
6868
foo2(...x2);
69+
70+
// Repros from #47754
71+
72+
type RestParams = [y: string] | [y: number];
73+
74+
type Signature = (x: string, ...rest: RestParams) => void;
75+
76+
type MergedParams = Parameters<Signature>; // [x: string, y: string] | [x: string, y: number]
77+
78+
declare let ff1: (...rest: [string, string] | [string, number]) => void;
79+
declare let ff2: (x: string, ...rest: [string] | [number]) => void;
80+
81+
ff1 = ff2;
82+
ff2 = ff1;
83+
84+
function ff3<A extends unknown[]>(s1: (...args: [x: string, ...rest: A | [number]]) => void, s2: (x: string, ...rest: A | [number]) => void) {
85+
s1 = s2;
86+
s2 = s1;
87+
}

0 commit comments

Comments
 (0)