From 29cdfb847a9aaecd350858749df8e29f43e07f8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Mon, 8 Jan 2024 01:05:30 +0100 Subject: [PATCH 1/2] Improve inference for a tuple target with 2 middle variadic elements and implied arity for the latter --- src/compiler/checker.ts | 7 ++- .../reference/variadicTuples3.symbols | 48 +++++++++++++++++++ .../baselines/reference/variadicTuples3.types | 48 +++++++++++++++++++ .../types/tuple/variadicTuples3.ts | 17 +++++++ 4 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/variadicTuples3.symbols create mode 100644 tests/baselines/reference/variadicTuples3.types create mode 100644 tests/cases/conformance/types/tuple/variadicTuples3.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7fcd96913ae06..d1dc85048dec9 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -25970,12 +25970,17 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (middleLength === 2) { if (elementFlags[startLength] & elementFlags[startLength + 1] & ElementFlags.Variadic) { // Middle of target is [...T, ...U] and source is tuple type - const targetInfo = getInferenceInfoForType(elementTypes[startLength]); + let 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]); inferFromTypes(sliceTupleType(source, startLength + targetInfo.impliedArity, endLength), elementTypes[startLength + 1]); } + else if ((targetInfo = getInferenceInfoForType(elementTypes[startLength + 1]))?.impliedArity !== undefined) { + // Infer slices from source based on implied arity of U. + inferFromTypes(sliceTupleType(source, startLength, endLength + targetInfo!.impliedArity), elementTypes[startLength]); + inferFromTypes(sliceTupleType(source, startLength + sourceArity - targetInfo!.impliedArity, endLength), elementTypes[startLength + 1]); + } } else if (elementFlags[startLength] & ElementFlags.Variadic && elementFlags[startLength + 1] & ElementFlags.Rest) { // Middle of target is [...T, ...rest] and source is tuple type diff --git a/tests/baselines/reference/variadicTuples3.symbols b/tests/baselines/reference/variadicTuples3.symbols new file mode 100644 index 0000000000000..6d84c775a7bfa --- /dev/null +++ b/tests/baselines/reference/variadicTuples3.symbols @@ -0,0 +1,48 @@ +//// [tests/cases/conformance/types/tuple/variadicTuples3.ts] //// + +=== variadicTuples3.ts === +// https://github.com/microsoft/TypeScript/issues/56970 + +function partialCallRev( +>partialCallRev : Symbol(partialCallRev, Decl(variadicTuples3.ts, 0, 0)) +>T : Symbol(T, Decl(variadicTuples3.ts, 2, 24)) +>U : Symbol(U, Decl(variadicTuples3.ts, 2, 49)) +>R : Symbol(R, Decl(variadicTuples3.ts, 2, 75)) + + f: (...args: [...U, ...T]) => R, +>f : Symbol(f, Decl(variadicTuples3.ts, 2, 79)) +>args : Symbol(args, Decl(variadicTuples3.ts, 3, 6)) +>U : Symbol(U, Decl(variadicTuples3.ts, 2, 49)) +>T : Symbol(T, Decl(variadicTuples3.ts, 2, 24)) +>R : Symbol(R, Decl(variadicTuples3.ts, 2, 75)) + + ...tailArgs: T +>tailArgs : Symbol(tailArgs, Decl(variadicTuples3.ts, 3, 34)) +>T : Symbol(T, Decl(variadicTuples3.ts, 2, 24)) + +) { + return (...headArgs: U) => f(...headArgs, ...tailArgs); +>headArgs : Symbol(headArgs, Decl(variadicTuples3.ts, 6, 10)) +>U : Symbol(U, Decl(variadicTuples3.ts, 2, 49)) +>f : Symbol(f, Decl(variadicTuples3.ts, 2, 79)) +>headArgs : Symbol(headArgs, Decl(variadicTuples3.ts, 6, 10)) +>tailArgs : Symbol(tailArgs, Decl(variadicTuples3.ts, 3, 34)) +} + +function te(a: number, b: number, c: number): number { +>te : Symbol(te, Decl(variadicTuples3.ts, 7, 1)) +>a : Symbol(a, Decl(variadicTuples3.ts, 9, 12)) +>b : Symbol(b, Decl(variadicTuples3.ts, 9, 22)) +>c : Symbol(c, Decl(variadicTuples3.ts, 9, 33)) + + return a + b + c; +>a : Symbol(a, Decl(variadicTuples3.ts, 9, 12)) +>b : Symbol(b, Decl(variadicTuples3.ts, 9, 22)) +>c : Symbol(c, Decl(variadicTuples3.ts, 9, 33)) +} + +const fn = partialCallRev(te, 1); +>fn : Symbol(fn, Decl(variadicTuples3.ts, 13, 5)) +>partialCallRev : Symbol(partialCallRev, Decl(variadicTuples3.ts, 0, 0)) +>te : Symbol(te, Decl(variadicTuples3.ts, 7, 1)) + diff --git a/tests/baselines/reference/variadicTuples3.types b/tests/baselines/reference/variadicTuples3.types new file mode 100644 index 0000000000000..f07032a8502fa --- /dev/null +++ b/tests/baselines/reference/variadicTuples3.types @@ -0,0 +1,48 @@ +//// [tests/cases/conformance/types/tuple/variadicTuples3.ts] //// + +=== variadicTuples3.ts === +// https://github.com/microsoft/TypeScript/issues/56970 + +function partialCallRev( +>partialCallRev : (f: (...args: [...U, ...T]) => R, ...tailArgs: T) => (...headArgs: U) => R + + f: (...args: [...U, ...T]) => R, +>f : (...args: [...U, ...T]) => R +>args : [...U, ...T] + + ...tailArgs: T +>tailArgs : T + +) { + return (...headArgs: U) => f(...headArgs, ...tailArgs); +>(...headArgs: U) => f(...headArgs, ...tailArgs) : (...headArgs: U) => R +>headArgs : U +>f(...headArgs, ...tailArgs) : R +>f : (...args: [...U, ...T]) => R +>...headArgs : any +>headArgs : U +>...tailArgs : any +>tailArgs : T +} + +function te(a: number, b: number, c: number): number { +>te : (a: number, b: number, c: number) => number +>a : number +>b : number +>c : number + + return a + b + c; +>a + b + c : number +>a + b : number +>a : number +>b : number +>c : number +} + +const fn = partialCallRev(te, 1); +>fn : (a: number, b: number) => number +>partialCallRev(te, 1) : (a: number, b: number) => number +>partialCallRev : (f: (...args: [...U, ...T]) => R, ...tailArgs: T) => (...headArgs: U) => R +>te : (a: number, b: number, c: number) => number +>1 : 1 + diff --git a/tests/cases/conformance/types/tuple/variadicTuples3.ts b/tests/cases/conformance/types/tuple/variadicTuples3.ts new file mode 100644 index 0000000000000..9c9c3ccd07a2d --- /dev/null +++ b/tests/cases/conformance/types/tuple/variadicTuples3.ts @@ -0,0 +1,17 @@ +// @strict: true +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/56970 + +function partialCallRev( + f: (...args: [...U, ...T]) => R, + ...tailArgs: T +) { + return (...headArgs: U) => f(...headArgs, ...tailArgs); +} + +function te(a: number, b: number, c: number): number { + return a + b + c; +} + +const fn = partialCallRev(te, 1); From ecd3b576c7bd0a45f607d7dc7fdbbcf19c53f1cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Mon, 8 Jan 2024 09:06:14 +0100 Subject: [PATCH 2/2] Fixed a case with extra trailing end element --- src/compiler/checker.ts | 2 +- .../reference/variadicTuples3.symbols | 140 +++++++++++++++--- .../baselines/reference/variadicTuples3.types | 114 ++++++++++++-- .../types/tuple/variadicTuples3.ts | 34 ++++- 4 files changed, 253 insertions(+), 37 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d1dc85048dec9..e8e85be90b04c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -25979,7 +25979,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { else if ((targetInfo = getInferenceInfoForType(elementTypes[startLength + 1]))?.impliedArity !== undefined) { // Infer slices from source based on implied arity of U. inferFromTypes(sliceTupleType(source, startLength, endLength + targetInfo!.impliedArity), elementTypes[startLength]); - inferFromTypes(sliceTupleType(source, startLength + sourceArity - targetInfo!.impliedArity, endLength), elementTypes[startLength + 1]); + inferFromTypes(sliceTupleType(source, startLength + sourceArity - endLength - targetInfo!.impliedArity, endLength), elementTypes[startLength + 1]); } } else if (elementFlags[startLength] & ElementFlags.Variadic && elementFlags[startLength + 1] & ElementFlags.Rest) { diff --git a/tests/baselines/reference/variadicTuples3.symbols b/tests/baselines/reference/variadicTuples3.symbols index 6d84c775a7bfa..8cbde3f5936f6 100644 --- a/tests/baselines/reference/variadicTuples3.symbols +++ b/tests/baselines/reference/variadicTuples3.symbols @@ -3,46 +3,138 @@ === variadicTuples3.ts === // https://github.com/microsoft/TypeScript/issues/56970 -function partialCallRev( ->partialCallRev : Symbol(partialCallRev, Decl(variadicTuples3.ts, 0, 0)) ->T : Symbol(T, Decl(variadicTuples3.ts, 2, 24)) ->U : Symbol(U, Decl(variadicTuples3.ts, 2, 49)) ->R : Symbol(R, Decl(variadicTuples3.ts, 2, 75)) +function partialCall1( +>partialCall1 : Symbol(partialCall1, Decl(variadicTuples3.ts, 0, 0)) +>T : Symbol(T, Decl(variadicTuples3.ts, 2, 22)) +>U : Symbol(U, Decl(variadicTuples3.ts, 2, 47)) +>R : Symbol(R, Decl(variadicTuples3.ts, 2, 73)) f: (...args: [...U, ...T]) => R, ->f : Symbol(f, Decl(variadicTuples3.ts, 2, 79)) +>f : Symbol(f, Decl(variadicTuples3.ts, 2, 77)) >args : Symbol(args, Decl(variadicTuples3.ts, 3, 6)) ->U : Symbol(U, Decl(variadicTuples3.ts, 2, 49)) ->T : Symbol(T, Decl(variadicTuples3.ts, 2, 24)) ->R : Symbol(R, Decl(variadicTuples3.ts, 2, 75)) +>U : Symbol(U, Decl(variadicTuples3.ts, 2, 47)) +>T : Symbol(T, Decl(variadicTuples3.ts, 2, 22)) +>R : Symbol(R, Decl(variadicTuples3.ts, 2, 73)) ...tailArgs: T >tailArgs : Symbol(tailArgs, Decl(variadicTuples3.ts, 3, 34)) ->T : Symbol(T, Decl(variadicTuples3.ts, 2, 24)) +>T : Symbol(T, Decl(variadicTuples3.ts, 2, 22)) ) { return (...headArgs: U) => f(...headArgs, ...tailArgs); >headArgs : Symbol(headArgs, Decl(variadicTuples3.ts, 6, 10)) ->U : Symbol(U, Decl(variadicTuples3.ts, 2, 49)) ->f : Symbol(f, Decl(variadicTuples3.ts, 2, 79)) +>U : Symbol(U, Decl(variadicTuples3.ts, 2, 47)) +>f : Symbol(f, Decl(variadicTuples3.ts, 2, 77)) >headArgs : Symbol(headArgs, Decl(variadicTuples3.ts, 6, 10)) >tailArgs : Symbol(tailArgs, Decl(variadicTuples3.ts, 3, 34)) } -function te(a: number, b: number, c: number): number { ->te : Symbol(te, Decl(variadicTuples3.ts, 7, 1)) ->a : Symbol(a, Decl(variadicTuples3.ts, 9, 12)) ->b : Symbol(b, Decl(variadicTuples3.ts, 9, 22)) ->c : Symbol(c, Decl(variadicTuples3.ts, 9, 33)) +function source1(a: number, b: number, c: number): number { +>source1 : Symbol(source1, Decl(variadicTuples3.ts, 7, 1)) +>a : Symbol(a, Decl(variadicTuples3.ts, 9, 17)) +>b : Symbol(b, Decl(variadicTuples3.ts, 9, 27)) +>c : Symbol(c, Decl(variadicTuples3.ts, 9, 38)) return a + b + c; ->a : Symbol(a, Decl(variadicTuples3.ts, 9, 12)) ->b : Symbol(b, Decl(variadicTuples3.ts, 9, 22)) ->c : Symbol(c, Decl(variadicTuples3.ts, 9, 33)) +>a : Symbol(a, Decl(variadicTuples3.ts, 9, 17)) +>b : Symbol(b, Decl(variadicTuples3.ts, 9, 27)) +>c : Symbol(c, Decl(variadicTuples3.ts, 9, 38)) } -const fn = partialCallRev(te, 1); ->fn : Symbol(fn, Decl(variadicTuples3.ts, 13, 5)) ->partialCallRev : Symbol(partialCallRev, Decl(variadicTuples3.ts, 0, 0)) ->te : Symbol(te, Decl(variadicTuples3.ts, 7, 1)) +const result1 = partialCall1(source1, 1); +>result1 : Symbol(result1, Decl(variadicTuples3.ts, 13, 5)) +>partialCall1 : Symbol(partialCall1, Decl(variadicTuples3.ts, 0, 0)) +>source1 : Symbol(source1, Decl(variadicTuples3.ts, 7, 1)) + +function partialCall2( +>partialCall2 : Symbol(partialCall2, Decl(variadicTuples3.ts, 13, 41)) +>T : Symbol(T, Decl(variadicTuples3.ts, 15, 22)) +>U : Symbol(U, Decl(variadicTuples3.ts, 15, 47)) +>R : Symbol(R, Decl(variadicTuples3.ts, 15, 73)) + + f: (...args: [number, ...U, ...T]) => R, +>f : Symbol(f, Decl(variadicTuples3.ts, 15, 77)) +>args : Symbol(args, Decl(variadicTuples3.ts, 16, 6)) +>U : Symbol(U, Decl(variadicTuples3.ts, 15, 47)) +>T : Symbol(T, Decl(variadicTuples3.ts, 15, 22)) +>R : Symbol(R, Decl(variadicTuples3.ts, 15, 73)) + + ...tailArgs: T +>tailArgs : Symbol(tailArgs, Decl(variadicTuples3.ts, 16, 42)) +>T : Symbol(T, Decl(variadicTuples3.ts, 15, 22)) + +) { + return (...headArgs: U) => f(0, ...headArgs, ...tailArgs); +>headArgs : Symbol(headArgs, Decl(variadicTuples3.ts, 19, 10)) +>U : Symbol(U, Decl(variadicTuples3.ts, 15, 47)) +>f : Symbol(f, Decl(variadicTuples3.ts, 15, 77)) +>headArgs : Symbol(headArgs, Decl(variadicTuples3.ts, 19, 10)) +>tailArgs : Symbol(tailArgs, Decl(variadicTuples3.ts, 16, 42)) +} + +function source2(a: number, b: number, c: number, d: number): number { +>source2 : Symbol(source2, Decl(variadicTuples3.ts, 20, 1)) +>a : Symbol(a, Decl(variadicTuples3.ts, 22, 17)) +>b : Symbol(b, Decl(variadicTuples3.ts, 22, 27)) +>c : Symbol(c, Decl(variadicTuples3.ts, 22, 38)) +>d : Symbol(d, Decl(variadicTuples3.ts, 22, 49)) + + return a + b + c + d; +>a : Symbol(a, Decl(variadicTuples3.ts, 22, 17)) +>b : Symbol(b, Decl(variadicTuples3.ts, 22, 27)) +>c : Symbol(c, Decl(variadicTuples3.ts, 22, 38)) +>d : Symbol(d, Decl(variadicTuples3.ts, 22, 49)) +} + +const result2 = partialCall2(source2, 1); +>result2 : Symbol(result2, Decl(variadicTuples3.ts, 26, 5)) +>partialCall2 : Symbol(partialCall2, Decl(variadicTuples3.ts, 13, 41)) +>source2 : Symbol(source2, Decl(variadicTuples3.ts, 20, 1)) + +function partialCall3( +>partialCall3 : Symbol(partialCall3, Decl(variadicTuples3.ts, 26, 41)) +>T : Symbol(T, Decl(variadicTuples3.ts, 28, 22)) +>U : Symbol(U, Decl(variadicTuples3.ts, 28, 47)) +>R : Symbol(R, Decl(variadicTuples3.ts, 28, 73)) + + f: (...args: [...U, ...T, number]) => R, +>f : Symbol(f, Decl(variadicTuples3.ts, 28, 77)) +>args : Symbol(args, Decl(variadicTuples3.ts, 29, 6)) +>U : Symbol(U, Decl(variadicTuples3.ts, 28, 47)) +>T : Symbol(T, Decl(variadicTuples3.ts, 28, 22)) +>R : Symbol(R, Decl(variadicTuples3.ts, 28, 73)) + + ...tailArgs: T +>tailArgs : Symbol(tailArgs, Decl(variadicTuples3.ts, 29, 42)) +>T : Symbol(T, Decl(variadicTuples3.ts, 28, 22)) + +) { + return (...headArgs: U) => f(...headArgs, ...tailArgs, 100); +>headArgs : Symbol(headArgs, Decl(variadicTuples3.ts, 32, 10)) +>U : Symbol(U, Decl(variadicTuples3.ts, 28, 47)) +>f : Symbol(f, Decl(variadicTuples3.ts, 28, 77)) +>headArgs : Symbol(headArgs, Decl(variadicTuples3.ts, 32, 10)) +>tailArgs : Symbol(tailArgs, Decl(variadicTuples3.ts, 29, 42)) +} + +function source3(a: number, b: number, c: number, d: number): number { +>source3 : Symbol(source3, Decl(variadicTuples3.ts, 33, 1)) +>a : Symbol(a, Decl(variadicTuples3.ts, 35, 17)) +>b : Symbol(b, Decl(variadicTuples3.ts, 35, 27)) +>c : Symbol(c, Decl(variadicTuples3.ts, 35, 38)) +>d : Symbol(d, Decl(variadicTuples3.ts, 35, 49)) + + return a + b + c + d; +>a : Symbol(a, Decl(variadicTuples3.ts, 35, 17)) +>b : Symbol(b, Decl(variadicTuples3.ts, 35, 27)) +>c : Symbol(c, Decl(variadicTuples3.ts, 35, 38)) +>d : Symbol(d, Decl(variadicTuples3.ts, 35, 49)) +} + +const result3 = partialCall3(source3, 1); +>result3 : Symbol(result3, Decl(variadicTuples3.ts, 39, 5)) +>partialCall3 : Symbol(partialCall3, Decl(variadicTuples3.ts, 26, 41)) +>source3 : Symbol(source3, Decl(variadicTuples3.ts, 33, 1)) + +export {} diff --git a/tests/baselines/reference/variadicTuples3.types b/tests/baselines/reference/variadicTuples3.types index f07032a8502fa..8f4a20f5ef393 100644 --- a/tests/baselines/reference/variadicTuples3.types +++ b/tests/baselines/reference/variadicTuples3.types @@ -3,8 +3,8 @@ === variadicTuples3.ts === // https://github.com/microsoft/TypeScript/issues/56970 -function partialCallRev( ->partialCallRev : (f: (...args: [...U, ...T]) => R, ...tailArgs: T) => (...headArgs: U) => R +function partialCall1( +>partialCall1 : (f: (...args: [...U, ...T]) => R, ...tailArgs: T) => (...headArgs: U) => R f: (...args: [...U, ...T]) => R, >f : (...args: [...U, ...T]) => R @@ -25,8 +25,8 @@ function partialCallRev( >tailArgs : T } -function te(a: number, b: number, c: number): number { ->te : (a: number, b: number, c: number) => number +function source1(a: number, b: number, c: number): number { +>source1 : (a: number, b: number, c: number) => number >a : number >b : number >c : number @@ -39,10 +39,106 @@ function te(a: number, b: number, c: number): number { >c : number } -const fn = partialCallRev(te, 1); ->fn : (a: number, b: number) => number ->partialCallRev(te, 1) : (a: number, b: number) => number ->partialCallRev : (f: (...args: [...U, ...T]) => R, ...tailArgs: T) => (...headArgs: U) => R ->te : (a: number, b: number, c: number) => number +const result1 = partialCall1(source1, 1); +>result1 : (a: number, b: number) => number +>partialCall1(source1, 1) : (a: number, b: number) => number +>partialCall1 : (f: (...args: [...U, ...T]) => R, ...tailArgs: T) => (...headArgs: U) => R +>source1 : (a: number, b: number, c: number) => number >1 : 1 +function partialCall2( +>partialCall2 : (f: (...args: [number, ...U, ...T]) => R, ...tailArgs: T) => (...headArgs: U) => R + + f: (...args: [number, ...U, ...T]) => R, +>f : (...args: [number, ...U, ...T]) => R +>args : [number, ...U, ...T] + + ...tailArgs: T +>tailArgs : T + +) { + return (...headArgs: U) => f(0, ...headArgs, ...tailArgs); +>(...headArgs: U) => f(0, ...headArgs, ...tailArgs) : (...headArgs: U) => R +>headArgs : U +>f(0, ...headArgs, ...tailArgs) : R +>f : (...args: [number, ...U, ...T]) => R +>0 : 0 +>...headArgs : any +>headArgs : U +>...tailArgs : any +>tailArgs : T +} + +function source2(a: number, b: number, c: number, d: number): number { +>source2 : (a: number, b: number, c: number, d: number) => number +>a : number +>b : number +>c : number +>d : number + + return a + b + c + d; +>a + b + c + d : number +>a + b + c : number +>a + b : number +>a : number +>b : number +>c : number +>d : number +} + +const result2 = partialCall2(source2, 1); +>result2 : (b: number, c: number) => number +>partialCall2(source2, 1) : (b: number, c: number) => number +>partialCall2 : (f: (...args: [number, ...U, ...T]) => R, ...tailArgs: T) => (...headArgs: U) => R +>source2 : (a: number, b: number, c: number, d: number) => number +>1 : 1 + +function partialCall3( +>partialCall3 : (f: (...args: [...U, ...T, number]) => R, ...tailArgs: T) => (...headArgs: U) => R + + f: (...args: [...U, ...T, number]) => R, +>f : (...args: [...U, ...T, number]) => R +>args : [...U, ...T, number] + + ...tailArgs: T +>tailArgs : T + +) { + return (...headArgs: U) => f(...headArgs, ...tailArgs, 100); +>(...headArgs: U) => f(...headArgs, ...tailArgs, 100) : (...headArgs: U) => R +>headArgs : U +>f(...headArgs, ...tailArgs, 100) : R +>f : (...args: [...U, ...T, number]) => R +>...headArgs : any +>headArgs : U +>...tailArgs : any +>tailArgs : T +>100 : 100 +} + +function source3(a: number, b: number, c: number, d: number): number { +>source3 : (a: number, b: number, c: number, d: number) => number +>a : number +>b : number +>c : number +>d : number + + return a + b + c + d; +>a + b + c + d : number +>a + b + c : number +>a + b : number +>a : number +>b : number +>c : number +>d : number +} + +const result3 = partialCall3(source3, 1); +>result3 : (a: number, b: number) => number +>partialCall3(source3, 1) : (a: number, b: number) => number +>partialCall3 : (f: (...args: [...U, ...T, number]) => R, ...tailArgs: T) => (...headArgs: U) => R +>source3 : (a: number, b: number, c: number, d: number) => number +>1 : 1 + +export {} + diff --git a/tests/cases/conformance/types/tuple/variadicTuples3.ts b/tests/cases/conformance/types/tuple/variadicTuples3.ts index 9c9c3ccd07a2d..3b530e85f195f 100644 --- a/tests/cases/conformance/types/tuple/variadicTuples3.ts +++ b/tests/cases/conformance/types/tuple/variadicTuples3.ts @@ -3,15 +3,43 @@ // https://github.com/microsoft/TypeScript/issues/56970 -function partialCallRev( +function partialCall1( f: (...args: [...U, ...T]) => R, ...tailArgs: T ) { return (...headArgs: U) => f(...headArgs, ...tailArgs); } -function te(a: number, b: number, c: number): number { +function source1(a: number, b: number, c: number): number { return a + b + c; } -const fn = partialCallRev(te, 1); +const result1 = partialCall1(source1, 1); + +function partialCall2( + f: (...args: [number, ...U, ...T]) => R, + ...tailArgs: T +) { + return (...headArgs: U) => f(0, ...headArgs, ...tailArgs); +} + +function source2(a: number, b: number, c: number, d: number): number { + return a + b + c + d; +} + +const result2 = partialCall2(source2, 1); + +function partialCall3( + f: (...args: [...U, ...T, number]) => R, + ...tailArgs: T +) { + return (...headArgs: U) => f(...headArgs, ...tailArgs, 100); +} + +function source3(a: number, b: number, c: number, d: number): number { + return a + b + c + d; +} + +const result3 = partialCall3(source3, 1); + +export {}