diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 48bc0da113816..6c5a5c1c94bc4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -27319,7 +27319,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const targetInfo = getInferenceInfoForType(elementTypes[startLength]); if (targetInfo && targetInfo.impliedArity !== undefined) { // Infer slices from source based on implied arity of T. - inferFromTypes(sliceTupleType(source, startLength, endLength + sourceArity - targetInfo.impliedArity), elementTypes[startLength]); + const otherImpliedArity = sourceArity - targetInfo.impliedArity - startLength - endLength; // implied arity of U + inferFromTypes(sliceTupleType(source, startLength, endLength + otherImpliedArity), elementTypes[startLength]); inferFromTypes(sliceTupleType(source, startLength + targetInfo.impliedArity, endLength), elementTypes[startLength + 1]); } } diff --git a/tests/baselines/reference/variadicTuples4.symbols b/tests/baselines/reference/variadicTuples4.symbols new file mode 100644 index 0000000000000..d573676fc15d6 --- /dev/null +++ b/tests/baselines/reference/variadicTuples4.symbols @@ -0,0 +1,120 @@ +//// [tests/cases/conformance/types/tuple/variadicTuples4.ts] //// + +=== variadicTuples4.ts === +// https://github.com/microsoft/TypeScript/issues/62561 + +function f( +>f : Symbol(f, Decl(variadicTuples4.ts, 0, 0)) +>T : Symbol(T, Decl(variadicTuples4.ts, 2, 11)) +>V : Symbol(V, Decl(variadicTuples4.ts, 2, 31)) + + x: [boolean, ...V, ...T], +>x : Symbol(x, Decl(variadicTuples4.ts, 2, 53)) +>V : Symbol(V, Decl(variadicTuples4.ts, 2, 31)) +>T : Symbol(T, Decl(variadicTuples4.ts, 2, 11)) + + ...args: V +>args : Symbol(args, Decl(variadicTuples4.ts, 3, 27)) +>V : Symbol(V, Decl(variadicTuples4.ts, 2, 31)) + +) { + return x; +>x : Symbol(x, Decl(variadicTuples4.ts, 2, 53)) +} + +const a = f([true, 2, "b", true], 1, "a"); // ok +>a : Symbol(a, Decl(variadicTuples4.ts, 9, 5)) +>f : Symbol(f, Decl(variadicTuples4.ts, 0, 0)) + +function f2( +>f2 : Symbol(f2, Decl(variadicTuples4.ts, 9, 42)) +>T : Symbol(T, Decl(variadicTuples4.ts, 11, 12)) +>V : Symbol(V, Decl(variadicTuples4.ts, 11, 32)) + + x: [boolean, ...V, ...T, string], +>x : Symbol(x, Decl(variadicTuples4.ts, 11, 54)) +>V : Symbol(V, Decl(variadicTuples4.ts, 11, 32)) +>T : Symbol(T, Decl(variadicTuples4.ts, 11, 12)) + + ...args: V +>args : Symbol(args, Decl(variadicTuples4.ts, 12, 35)) +>V : Symbol(V, Decl(variadicTuples4.ts, 11, 32)) + +) { + return x; +>x : Symbol(x, Decl(variadicTuples4.ts, 11, 54)) +} + +const a2 = f2([true, 2, "b", true, "c"], 1, "a"); // ok +>a2 : Symbol(a2, Decl(variadicTuples4.ts, 18, 5)) +>f2 : Symbol(f2, Decl(variadicTuples4.ts, 9, 42)) + +function f3( +>f3 : Symbol(f3, Decl(variadicTuples4.ts, 18, 49)) +>T : Symbol(T, Decl(variadicTuples4.ts, 20, 12)) +>V : Symbol(V, Decl(variadicTuples4.ts, 20, 32)) + + x: [boolean, ...V, ...T, string, number], +>x : Symbol(x, Decl(variadicTuples4.ts, 20, 54)) +>V : Symbol(V, Decl(variadicTuples4.ts, 20, 32)) +>T : Symbol(T, Decl(variadicTuples4.ts, 20, 12)) + + ...args: V +>args : Symbol(args, Decl(variadicTuples4.ts, 21, 43)) +>V : Symbol(V, Decl(variadicTuples4.ts, 20, 32)) + +) { + return x; +>x : Symbol(x, Decl(variadicTuples4.ts, 20, 54)) +} + +const a3 = f3([true, 2, "b", true, "c", 3], 1, "a"); // ok +>a3 : Symbol(a3, Decl(variadicTuples4.ts, 27, 5)) +>f3 : Symbol(f3, Decl(variadicTuples4.ts, 18, 49)) + +function f4( +>f4 : Symbol(f4, Decl(variadicTuples4.ts, 27, 52)) +>T : Symbol(T, Decl(variadicTuples4.ts, 29, 12)) +>V : Symbol(V, Decl(variadicTuples4.ts, 29, 32)) + + x: [boolean, boolean, boolean, ...V, ...T, string, number], +>x : Symbol(x, Decl(variadicTuples4.ts, 29, 54)) +>V : Symbol(V, Decl(variadicTuples4.ts, 29, 32)) +>T : Symbol(T, Decl(variadicTuples4.ts, 29, 12)) + + ...args: V +>args : Symbol(args, Decl(variadicTuples4.ts, 30, 61)) +>V : Symbol(V, Decl(variadicTuples4.ts, 29, 32)) + +) { + return x; +>x : Symbol(x, Decl(variadicTuples4.ts, 29, 54)) +} + +const a4 = f4([true, true, true, 2, "b", true, "c", 3], 1, "a"); // ok +>a4 : Symbol(a4, Decl(variadicTuples4.ts, 36, 5)) +>f4 : Symbol(f4, Decl(variadicTuples4.ts, 27, 52)) + +function f5( +>f5 : Symbol(f5, Decl(variadicTuples4.ts, 36, 64)) +>T : Symbol(T, Decl(variadicTuples4.ts, 38, 12)) +>V : Symbol(V, Decl(variadicTuples4.ts, 38, 32)) + + x: [boolean, boolean, boolean, ...V, ...T], +>x : Symbol(x, Decl(variadicTuples4.ts, 38, 54)) +>V : Symbol(V, Decl(variadicTuples4.ts, 38, 32)) +>T : Symbol(T, Decl(variadicTuples4.ts, 38, 12)) + + ...args: V +>args : Symbol(args, Decl(variadicTuples4.ts, 39, 45)) +>V : Symbol(V, Decl(variadicTuples4.ts, 38, 32)) + +) { + return x; +>x : Symbol(x, Decl(variadicTuples4.ts, 38, 54)) +} + +const a5 = f5([true, true, true, 2, "b", true], 1, "a"); // ok +>a5 : Symbol(a5, Decl(variadicTuples4.ts, 45, 5)) +>f5 : Symbol(f5, Decl(variadicTuples4.ts, 36, 64)) + diff --git a/tests/baselines/reference/variadicTuples4.types b/tests/baselines/reference/variadicTuples4.types new file mode 100644 index 0000000000000..ff46b3ee54958 --- /dev/null +++ b/tests/baselines/reference/variadicTuples4.types @@ -0,0 +1,223 @@ +//// [tests/cases/conformance/types/tuple/variadicTuples4.ts] //// + +=== variadicTuples4.ts === +// https://github.com/microsoft/TypeScript/issues/62561 + +function f( +>f : (x: [boolean, ...V, ...T], ...args: V) => [boolean, ...V, ...T] +> : ^ ^^^^^^^^^ ^^ ^^^^^^^^^ ^^ ^^ ^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^ + + x: [boolean, ...V, ...T], +>x : [boolean, ...V, ...T] +> : ^^^^^^^^^^^^^^^^^^^^^ + + ...args: V +>args : V +> : ^ + +) { + return x; +>x : [boolean, ...V, ...T] +> : ^^^^^^^^^^^^^^^^^^^^^ +} + +const a = f([true, 2, "b", true], 1, "a"); // ok +>a : [boolean, number, string, boolean] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>f([true, 2, "b", true], 1, "a") : [boolean, number, string, boolean] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>f : (x: [boolean, ...V, ...T], ...args: V) => [boolean, ...V, ...T] +> : ^ ^^^^^^^^^ ^^ ^^^^^^^^^ ^^ ^^ ^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^ +>[true, 2, "b", true] : [true, number, string, true] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>true : true +> : ^^^^ +>2 : 2 +> : ^ +>"b" : "b" +> : ^^^ +>true : true +> : ^^^^ +>1 : 1 +> : ^ +>"a" : "a" +> : ^^^ + +function f2( +>f2 : (x: [boolean, ...V, ...T, string], ...args: V) => [boolean, ...V, ...T, string] +> : ^ ^^^^^^^^^ ^^ ^^^^^^^^^ ^^ ^^ ^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + x: [boolean, ...V, ...T, string], +>x : [boolean, ...V, ...T, string] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + ...args: V +>args : V +> : ^ + +) { + return x; +>x : [boolean, ...V, ...T, string] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +} + +const a2 = f2([true, 2, "b", true, "c"], 1, "a"); // ok +>a2 : [boolean, number, string, boolean, string] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>f2([true, 2, "b", true, "c"], 1, "a") : [boolean, number, string, boolean, string] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>f2 : (x: [boolean, ...V, ...T, string], ...args: V) => [boolean, ...V, ...T, string] +> : ^ ^^^^^^^^^ ^^ ^^^^^^^^^ ^^ ^^ ^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>[true, 2, "b", true, "c"] : [true, number, string, true, string] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>true : true +> : ^^^^ +>2 : 2 +> : ^ +>"b" : "b" +> : ^^^ +>true : true +> : ^^^^ +>"c" : "c" +> : ^^^ +>1 : 1 +> : ^ +>"a" : "a" +> : ^^^ + +function f3( +>f3 : (x: [boolean, ...V, ...T, string, number], ...args: V) => [boolean, ...V, ...T, string, number] +> : ^ ^^^^^^^^^ ^^ ^^^^^^^^^ ^^ ^^ ^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + x: [boolean, ...V, ...T, string, number], +>x : [boolean, ...V, ...T, string, number] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + ...args: V +>args : V +> : ^ + +) { + return x; +>x : [boolean, ...V, ...T, string, number] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +} + +const a3 = f3([true, 2, "b", true, "c", 3], 1, "a"); // ok +>a3 : [boolean, number, string, boolean, string, number] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>f3([true, 2, "b", true, "c", 3], 1, "a") : [boolean, number, string, boolean, string, number] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>f3 : (x: [boolean, ...V, ...T, string, number], ...args: V) => [boolean, ...V, ...T, string, number] +> : ^ ^^^^^^^^^ ^^ ^^^^^^^^^ ^^ ^^ ^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>[true, 2, "b", true, "c", 3] : [true, number, string, true, string, number] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>true : true +> : ^^^^ +>2 : 2 +> : ^ +>"b" : "b" +> : ^^^ +>true : true +> : ^^^^ +>"c" : "c" +> : ^^^ +>3 : 3 +> : ^ +>1 : 1 +> : ^ +>"a" : "a" +> : ^^^ + +function f4( +>f4 : (x: [boolean, boolean, boolean, ...V, ...T, string, number], ...args: V) => [boolean, boolean, boolean, ...V, ...T, string, number] +> : ^ ^^^^^^^^^ ^^ ^^^^^^^^^ ^^ ^^ ^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + x: [boolean, boolean, boolean, ...V, ...T, string, number], +>x : [boolean, boolean, boolean, ...V, ...T, string, number] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + ...args: V +>args : V +> : ^ + +) { + return x; +>x : [boolean, boolean, boolean, ...V, ...T, string, number] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +} + +const a4 = f4([true, true, true, 2, "b", true, "c", 3], 1, "a"); // ok +>a4 : [boolean, boolean, boolean, number, string, boolean, string, number] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>f4([true, true, true, 2, "b", true, "c", 3], 1, "a") : [boolean, boolean, boolean, number, string, boolean, string, number] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>f4 : (x: [boolean, boolean, boolean, ...V, ...T, string, number], ...args: V) => [boolean, boolean, boolean, ...V, ...T, string, number] +> : ^ ^^^^^^^^^ ^^ ^^^^^^^^^ ^^ ^^ ^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>[true, true, true, 2, "b", true, "c", 3] : [true, true, true, number, string, true, string, number] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>true : true +> : ^^^^ +>true : true +> : ^^^^ +>true : true +> : ^^^^ +>2 : 2 +> : ^ +>"b" : "b" +> : ^^^ +>true : true +> : ^^^^ +>"c" : "c" +> : ^^^ +>3 : 3 +> : ^ +>1 : 1 +> : ^ +>"a" : "a" +> : ^^^ + +function f5( +>f5 : (x: [boolean, boolean, boolean, ...V, ...T], ...args: V) => [boolean, boolean, boolean, ...V, ...T] +> : ^ ^^^^^^^^^ ^^ ^^^^^^^^^ ^^ ^^ ^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + x: [boolean, boolean, boolean, ...V, ...T], +>x : [boolean, boolean, boolean, ...V, ...T] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + ...args: V +>args : V +> : ^ + +) { + return x; +>x : [boolean, boolean, boolean, ...V, ...T] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +} + +const a5 = f5([true, true, true, 2, "b", true], 1, "a"); // ok +>a5 : [boolean, boolean, boolean, number, string, boolean] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>f5([true, true, true, 2, "b", true], 1, "a") : [boolean, boolean, boolean, number, string, boolean] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>f5 : (x: [boolean, boolean, boolean, ...V, ...T], ...args: V) => [boolean, boolean, boolean, ...V, ...T] +> : ^ ^^^^^^^^^ ^^ ^^^^^^^^^ ^^ ^^ ^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>[true, true, true, 2, "b", true] : [true, true, true, number, string, true] +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>true : true +> : ^^^^ +>true : true +> : ^^^^ +>true : true +> : ^^^^ +>2 : 2 +> : ^ +>"b" : "b" +> : ^^^ +>true : true +> : ^^^^ +>1 : 1 +> : ^ +>"a" : "a" +> : ^^^ + diff --git a/tests/cases/conformance/types/tuple/variadicTuples4.ts b/tests/cases/conformance/types/tuple/variadicTuples4.ts new file mode 100644 index 0000000000000..9df1ba810bc67 --- /dev/null +++ b/tests/cases/conformance/types/tuple/variadicTuples4.ts @@ -0,0 +1,49 @@ +// @strict: true +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/62561 + +function f( + x: [boolean, ...V, ...T], + ...args: V +) { + return x; +} + +const a = f([true, 2, "b", true], 1, "a"); // ok + +function f2( + x: [boolean, ...V, ...T, string], + ...args: V +) { + return x; +} + +const a2 = f2([true, 2, "b", true, "c"], 1, "a"); // ok + +function f3( + x: [boolean, ...V, ...T, string, number], + ...args: V +) { + return x; +} + +const a3 = f3([true, 2, "b", true, "c", 3], 1, "a"); // ok + +function f4( + x: [boolean, boolean, boolean, ...V, ...T, string, number], + ...args: V +) { + return x; +} + +const a4 = f4([true, true, true, 2, "b", true, "c", 3], 1, "a"); // ok + +function f5( + x: [boolean, boolean, boolean, ...V, ...T], + ...args: V +) { + return x; +} + +const a5 = f5([true, true, true, 2, "b", true], 1, "a"); // ok