diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index cbd86af7c4334..4a5a85db1398b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -17671,10 +17671,6 @@ namespace ts { if (sourceRestType || targetRestType) { void instantiateType(sourceRestType || targetRestType, reportUnreliableMarkers); } - if (sourceRestType && targetRestType && sourceCount !== targetCount) { - // We're not able to relate misaligned complex rest parameters - return Ternary.False; - } const kind = target.declaration ? target.declaration.kind : SyntaxKind.Unknown; const strictVariance = !(checkMode & SignatureCheckMode.Callback) && strictFunctionTypes && kind !== SyntaxKind.MethodDeclaration && diff --git a/tests/baselines/reference/genericRestParameters3.errors.txt b/tests/baselines/reference/genericRestParameters3.errors.txt index 0f2612f6b80d3..d306bbf3a6748 100644 --- a/tests/baselines/reference/genericRestParameters3.errors.txt +++ b/tests/baselines/reference/genericRestParameters3.errors.txt @@ -4,7 +4,6 @@ tests/cases/conformance/types/rest/genericRestParameters3.ts(17,11): error TS234 tests/cases/conformance/types/rest/genericRestParameters3.ts(18,1): error TS2345: Argument of type '[]' is not assignable to parameter of type '[string] | [number, boolean]'. Type '[]' is not assignable to type '[number, boolean]'. Source has 0 element(s) but target requires 2. -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'. 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'. Types of parameters 'y' and 'args' are incompatible. 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 Type '[string] | [number, boolean]' is not assignable to type '[y: number, z: boolean]'. Type '[string]' is not assignable to type '[y: number, z: boolean]'. Source has 1 element(s) but target requires 2. -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'. tests/cases/conformance/types/rest/genericRestParameters3.ts(35,1): error TS2554: Expected 1 arguments, but got 0. tests/cases/conformance/types/rest/genericRestParameters3.ts(36,21): error TS2345: Argument of type 'number' is not assignable to parameter of type '(...args: CoolArray) => void'. tests/cases/conformance/types/rest/genericRestParameters3.ts(37,21): error TS2345: Argument of type '(cb: (...args: T) => void) => void' is not assignable to parameter of type '(...args: CoolArray) => void'. @@ -36,7 +34,7 @@ tests/cases/conformance/types/rest/genericRestParameters3.ts(59,5): error TS2345 Source has 1 element(s) but target requires 2. -==== tests/cases/conformance/types/rest/genericRestParameters3.ts (15 errors) ==== +==== tests/cases/conformance/types/rest/genericRestParameters3.ts (13 errors) ==== declare let f1: (x: string, ...args: [string] | [number, boolean]) => void; declare let f2: (x: string, y: string) => void; 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 f2 = f1; f3 = f1; - f4 = f1; // Error, misaligned complex rest types - ~~ -!!! error TS2322: Type '(x: string, ...args: [string] | [number, boolean]) => void' is not assignable to type '(...args: [string, string] | [string, number, boolean]) => void'. + f4 = f1; f1 = f2; // Error ~~ !!! 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 !!! error TS2322: Type '[string] | [number, boolean]' is not assignable to type '[y: number, z: boolean]'. !!! error TS2322: Type '[string]' is not assignable to type '[y: number, z: boolean]'. !!! error TS2322: Source has 1 element(s) but target requires 2. - f1 = f4; // Error, misaligned complex rest types - ~~ -!!! error TS2322: Type '(...args: [string, string] | [string, number, boolean]) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'. + f1 = f4; // Repro from #26110 @@ -159,4 +153,23 @@ tests/cases/conformance/types/rest/genericRestParameters3.ts(59,5): error TS2345 declare function foo2(...args: string[] | number[]): void; let x2: ReadonlyArray = ["hello"]; foo2(...x2); + + // Repros from #47754 + + type RestParams = [y: string] | [y: number]; + + type Signature = (x: string, ...rest: RestParams) => void; + + type MergedParams = Parameters; // [x: string, y: string] | [x: string, y: number] + + declare let ff1: (...rest: [string, string] | [string, number]) => void; + declare let ff2: (x: string, ...rest: [string] | [number]) => void; + + ff1 = ff2; + ff2 = ff1; + + function ff3(s1: (...args: [x: string, ...rest: A | [number]]) => void, s2: (x: string, ...rest: A | [number]) => void) { + s1 = s2; + s2 = s1; + } \ No newline at end of file diff --git a/tests/baselines/reference/genericRestParameters3.js b/tests/baselines/reference/genericRestParameters3.js index d085966b12ebd..880ebf286a560 100644 --- a/tests/baselines/reference/genericRestParameters3.js +++ b/tests/baselines/reference/genericRestParameters3.js @@ -20,10 +20,10 @@ f1("foo"); // Error f2 = f1; f3 = f1; -f4 = f1; // Error, misaligned complex rest types +f4 = f1; f1 = f2; // Error f1 = f3; // Error -f1 = f4; // Error, misaligned complex rest types +f1 = f4; // Repro from #26110 @@ -64,6 +64,25 @@ hmm("what"); // no error? A = [] | [number, string] ? declare function foo2(...args: string[] | number[]): void; let x2: ReadonlyArray = ["hello"]; foo2(...x2); + +// Repros from #47754 + +type RestParams = [y: string] | [y: number]; + +type Signature = (x: string, ...rest: RestParams) => void; + +type MergedParams = Parameters; // [x: string, y: string] | [x: string, y: number] + +declare let ff1: (...rest: [string, string] | [string, number]) => void; +declare let ff2: (x: string, ...rest: [string] | [number]) => void; + +ff1 = ff2; +ff2 = ff1; + +function ff3(s1: (...args: [x: string, ...rest: A | [number]]) => void, s2: (x: string, ...rest: A | [number]) => void) { + s1 = s2; + s2 = s1; +} //// [genericRestParameters3.js] @@ -87,10 +106,10 @@ f1("foo", 10); // Error f1("foo"); // Error f2 = f1; f3 = f1; -f4 = f1; // Error, misaligned complex rest types +f4 = f1; f1 = f2; // Error f1 = f3; // Error -f1 = f4; // Error, misaligned complex rest types +f1 = f4; foo(); // Error foo(100); // Error foo(foo); // Error @@ -112,6 +131,12 @@ hmm(1, "s"); // okay, A = [1, "s"] hmm("what"); // no error? A = [] | [number, string] ? var x2 = ["hello"]; foo2.apply(void 0, x2); +ff1 = ff2; +ff2 = ff1; +function ff3(s1, s2) { + s1 = s2; + s2 = s1; +} //// [genericRestParameters3.d.ts] @@ -135,3 +160,9 @@ declare const ca: CoolArray; declare function hmm(...args: A): void; declare function foo2(...args: string[] | number[]): void; declare let x2: ReadonlyArray; +declare type RestParams = [y: string] | [y: number]; +declare type Signature = (x: string, ...rest: RestParams) => void; +declare type MergedParams = Parameters; +declare let ff1: (...rest: [string, string] | [string, number]) => void; +declare let ff2: (x: string, ...rest: [string] | [number]) => void; +declare function ff3(s1: (...args: [x: string, ...rest: A | [number]]) => void, s2: (x: string, ...rest: A | [number]) => void): void; diff --git a/tests/baselines/reference/genericRestParameters3.symbols b/tests/baselines/reference/genericRestParameters3.symbols index 9bad8685db190..292aacfb8cdc8 100644 --- a/tests/baselines/reference/genericRestParameters3.symbols +++ b/tests/baselines/reference/genericRestParameters3.symbols @@ -67,7 +67,7 @@ f3 = f1; >f3 : Symbol(f3, Decl(genericRestParameters3.ts, 2, 11)) >f1 : Symbol(f1, Decl(genericRestParameters3.ts, 0, 11)) -f4 = f1; // Error, misaligned complex rest types +f4 = f1; >f4 : Symbol(f4, Decl(genericRestParameters3.ts, 3, 11)) >f1 : Symbol(f1, Decl(genericRestParameters3.ts, 0, 11)) @@ -79,7 +79,7 @@ f1 = f3; // Error >f1 : Symbol(f1, Decl(genericRestParameters3.ts, 0, 11)) >f3 : Symbol(f3, Decl(genericRestParameters3.ts, 2, 11)) -f1 = f4; // Error, misaligned complex rest types +f1 = f4; >f1 : Symbol(f1, Decl(genericRestParameters3.ts, 0, 11)) >f4 : Symbol(f4, Decl(genericRestParameters3.ts, 3, 11)) @@ -190,3 +190,56 @@ foo2(...x2); >foo2 : Symbol(foo2, Decl(genericRestParameters3.ts, 58, 12)) >x2 : Symbol(x2, Decl(genericRestParameters3.ts, 63, 3)) +// Repros from #47754 + +type RestParams = [y: string] | [y: number]; +>RestParams : Symbol(RestParams, Decl(genericRestParameters3.ts, 64, 12)) + +type Signature = (x: string, ...rest: RestParams) => void; +>Signature : Symbol(Signature, Decl(genericRestParameters3.ts, 68, 44)) +>x : Symbol(x, Decl(genericRestParameters3.ts, 70, 18)) +>rest : Symbol(rest, Decl(genericRestParameters3.ts, 70, 28)) +>RestParams : Symbol(RestParams, Decl(genericRestParameters3.ts, 64, 12)) + +type MergedParams = Parameters; // [x: string, y: string] | [x: string, y: number] +>MergedParams : Symbol(MergedParams, Decl(genericRestParameters3.ts, 70, 58)) +>Parameters : Symbol(Parameters, Decl(lib.es5.d.ts, --, --)) +>Signature : Symbol(Signature, Decl(genericRestParameters3.ts, 68, 44)) + +declare let ff1: (...rest: [string, string] | [string, number]) => void; +>ff1 : Symbol(ff1, Decl(genericRestParameters3.ts, 74, 11)) +>rest : Symbol(rest, Decl(genericRestParameters3.ts, 74, 18)) + +declare let ff2: (x: string, ...rest: [string] | [number]) => void; +>ff2 : Symbol(ff2, Decl(genericRestParameters3.ts, 75, 11)) +>x : Symbol(x, Decl(genericRestParameters3.ts, 75, 18)) +>rest : Symbol(rest, Decl(genericRestParameters3.ts, 75, 28)) + +ff1 = ff2; +>ff1 : Symbol(ff1, Decl(genericRestParameters3.ts, 74, 11)) +>ff2 : Symbol(ff2, Decl(genericRestParameters3.ts, 75, 11)) + +ff2 = ff1; +>ff2 : Symbol(ff2, Decl(genericRestParameters3.ts, 75, 11)) +>ff1 : Symbol(ff1, Decl(genericRestParameters3.ts, 74, 11)) + +function ff3(s1: (...args: [x: string, ...rest: A | [number]]) => void, s2: (x: string, ...rest: A | [number]) => void) { +>ff3 : Symbol(ff3, Decl(genericRestParameters3.ts, 78, 10)) +>A : Symbol(A, Decl(genericRestParameters3.ts, 80, 13)) +>s1 : Symbol(s1, Decl(genericRestParameters3.ts, 80, 34)) +>args : Symbol(args, Decl(genericRestParameters3.ts, 80, 39)) +>A : Symbol(A, Decl(genericRestParameters3.ts, 80, 13)) +>s2 : Symbol(s2, Decl(genericRestParameters3.ts, 80, 92)) +>x : Symbol(x, Decl(genericRestParameters3.ts, 80, 98)) +>rest : Symbol(rest, Decl(genericRestParameters3.ts, 80, 108)) +>A : Symbol(A, Decl(genericRestParameters3.ts, 80, 13)) + + s1 = s2; +>s1 : Symbol(s1, Decl(genericRestParameters3.ts, 80, 34)) +>s2 : Symbol(s2, Decl(genericRestParameters3.ts, 80, 92)) + + s2 = s1; +>s2 : Symbol(s2, Decl(genericRestParameters3.ts, 80, 92)) +>s1 : Symbol(s1, Decl(genericRestParameters3.ts, 80, 34)) +} + diff --git a/tests/baselines/reference/genericRestParameters3.types b/tests/baselines/reference/genericRestParameters3.types index add3bbab9d51e..be5b2c2091d05 100644 --- a/tests/baselines/reference/genericRestParameters3.types +++ b/tests/baselines/reference/genericRestParameters3.types @@ -93,7 +93,7 @@ f3 = f1; >f3 : (x: string, y: number, z: boolean) => void >f1 : (x: string, ...args: [string] | [number, boolean]) => void -f4 = f1; // Error, misaligned complex rest types +f4 = f1; >f4 = f1 : (x: string, ...args: [string] | [number, boolean]) => void >f4 : (...args: [string, string] | [string, number, boolean]) => void >f1 : (x: string, ...args: [string] | [number, boolean]) => void @@ -108,7 +108,7 @@ f1 = f3; // Error >f1 : (x: string, ...args: [string] | [number, boolean]) => void >f3 : (x: string, y: number, z: boolean) => void -f1 = f4; // Error, misaligned complex rest types +f1 = f4; >f1 = f4 : (...args: [string, string] | [string, number, boolean]) => void >f1 : (x: string, ...args: [string] | [number, boolean]) => void >f4 : (...args: [string, string] | [string, number, boolean]) => void @@ -227,3 +227,54 @@ foo2(...x2); >...x2 : string >x2 : readonly string[] +// Repros from #47754 + +type RestParams = [y: string] | [y: number]; +>RestParams : RestParams + +type Signature = (x: string, ...rest: RestParams) => void; +>Signature : Signature +>x : string +>rest : RestParams + +type MergedParams = Parameters; // [x: string, y: string] | [x: string, y: number] +>MergedParams : [x: string, y: string] | [x: string, y: number] + +declare let ff1: (...rest: [string, string] | [string, number]) => void; +>ff1 : (...rest: [string, string] | [string, number]) => void +>rest : [string, string] | [string, number] + +declare let ff2: (x: string, ...rest: [string] | [number]) => void; +>ff2 : (x: string, ...rest: [string] | [number]) => void +>x : string +>rest : [string] | [number] + +ff1 = ff2; +>ff1 = ff2 : (x: string, ...rest: [string] | [number]) => void +>ff1 : (...rest: [string, string] | [string, number]) => void +>ff2 : (x: string, ...rest: [string] | [number]) => void + +ff2 = ff1; +>ff2 = ff1 : (...rest: [string, string] | [string, number]) => void +>ff2 : (x: string, ...rest: [string] | [number]) => void +>ff1 : (...rest: [string, string] | [string, number]) => void + +function ff3(s1: (...args: [x: string, ...rest: A | [number]]) => void, s2: (x: string, ...rest: A | [number]) => void) { +>ff3 : (s1: (...args: [x: string, ...rest: A | [number]]) => void, s2: (x: string, ...rest: A | [number]) => void) => void +>s1 : (...args: [x: string, ...rest: A | [number]]) => void +>args : [string, number] | [x: string, ...rest: A] +>s2 : (x: string, ...rest: A | [number]) => void +>x : string +>rest : [number] | A + + s1 = s2; +>s1 = s2 : (x: string, ...rest: [number] | A) => void +>s1 : (...args: [string, number] | [x: string, ...rest: A]) => void +>s2 : (x: string, ...rest: [number] | A) => void + + s2 = s1; +>s2 = s1 : (...args: [string, number] | [x: string, ...rest: A]) => void +>s2 : (x: string, ...rest: [number] | A) => void +>s1 : (...args: [string, number] | [x: string, ...rest: A]) => void +} + diff --git a/tests/cases/conformance/types/rest/genericRestParameters3.ts b/tests/cases/conformance/types/rest/genericRestParameters3.ts index 4bcc4741695d3..7cd481e2c7ac6 100644 --- a/tests/cases/conformance/types/rest/genericRestParameters3.ts +++ b/tests/cases/conformance/types/rest/genericRestParameters3.ts @@ -22,10 +22,10 @@ f1("foo"); // Error f2 = f1; f3 = f1; -f4 = f1; // Error, misaligned complex rest types +f4 = f1; f1 = f2; // Error f1 = f3; // Error -f1 = f4; // Error, misaligned complex rest types +f1 = f4; // Repro from #26110 @@ -66,3 +66,22 @@ hmm("what"); // no error? A = [] | [number, string] ? declare function foo2(...args: string[] | number[]): void; let x2: ReadonlyArray = ["hello"]; foo2(...x2); + +// Repros from #47754 + +type RestParams = [y: string] | [y: number]; + +type Signature = (x: string, ...rest: RestParams) => void; + +type MergedParams = Parameters; // [x: string, y: string] | [x: string, y: number] + +declare let ff1: (...rest: [string, string] | [string, number]) => void; +declare let ff2: (x: string, ...rest: [string] | [number]) => void; + +ff1 = ff2; +ff2 = ff1; + +function ff3(s1: (...args: [x: string, ...rest: A | [number]]) => void, s2: (x: string, ...rest: A | [number]) => void) { + s1 = s2; + s2 = s1; +}