From f3691a3a03df3ed832cae43cb370892b01c028c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Wed, 27 Aug 2025 10:07:54 +0200 Subject: [PATCH 1/2] Allow parameters to be contextually-typed based on contextual rest instantiated using return mapper --- src/compiler/checker.ts | 4 +- ...singInstantiantedRestReturnMapper1.symbols | 42 ++++++++++++++ ...sUsingInstantiantedRestReturnMapper1.types | 56 +++++++++++++++++++ ...tersUsingInstantiantedRestReturnMapper1.ts | 16 ++++++ 4 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.symbols create mode 100644 tests/baselines/reference/contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.types create mode 100644 tests/cases/compiler/contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 75be36474222f..b34e990ef7746 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -39547,7 +39547,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { inferFromAnnotatedParametersAndReturn(signature, contextualSignature, inferenceContext!); const restType = getEffectiveRestType(contextualSignature); if (restType && restType.flags & TypeFlags.TypeParameter) { - instantiatedContextualSignature = instantiateSignature(contextualSignature, inferenceContext!.nonFixingMapper); + const info = find(inferenceContext!.inferences, info => info.typeParameter === restType); + const mapper = combineTypeMappers(info && !hasInferenceCandidates(info) ? inferenceContext!.returnMapper : undefined, inferenceContext!.nonFixingMapper); + instantiatedContextualSignature = instantiateSignature(contextualSignature, mapper); } } instantiatedContextualSignature ||= inferenceContext ? diff --git a/tests/baselines/reference/contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.symbols b/tests/baselines/reference/contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.symbols new file mode 100644 index 0000000000000..63906fbf313c2 --- /dev/null +++ b/tests/baselines/reference/contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.symbols @@ -0,0 +1,42 @@ +//// [tests/cases/compiler/contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts] //// + +=== contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts === +// https://github.com/microsoft/TypeScript/issues/62336 + +declare function call(fn: (a: string, b: T) => unknown): (b: T) => unknown; +>call : Symbol(call, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 0, 0)) +>T : Symbol(T, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 2, 22)) +>fn : Symbol(fn, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 2, 25)) +>a : Symbol(a, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 2, 30)) +>b : Symbol(b, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 2, 40)) +>T : Symbol(T, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 2, 22)) +>b : Symbol(b, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 2, 61)) +>T : Symbol(T, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 2, 22)) + +declare function fn( +>fn : Symbol(fn, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 2, 78)) +>Args : Symbol(Args, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 4, 20)) + + fn: (...args: Args) => unknown, +>fn : Symbol(fn, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 4, 40)) +>args : Symbol(args, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 5, 7)) +>Args : Symbol(Args, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 4, 20)) + +): (...args: Args) => unknown; +>args : Symbol(args, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 6, 4)) +>Args : Symbol(Args, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 4, 20)) + +call( +>call : Symbol(call, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 0, 0)) + + fn(function (a, b: number) { +>fn : Symbol(fn, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 2, 78)) +>a : Symbol(a, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 9, 15)) +>b : Symbol(b, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 9, 17)) + + a; // string +>a : Symbol(a, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 9, 15)) + + }), +); + diff --git a/tests/baselines/reference/contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.types b/tests/baselines/reference/contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.types new file mode 100644 index 0000000000000..9e95864076857 --- /dev/null +++ b/tests/baselines/reference/contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.types @@ -0,0 +1,56 @@ +//// [tests/cases/compiler/contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts] //// + +=== contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts === +// https://github.com/microsoft/TypeScript/issues/62336 + +declare function call(fn: (a: string, b: T) => unknown): (b: T) => unknown; +>call : (fn: (a: string, b: T) => unknown) => (b: T) => unknown +> : ^ ^^ ^^ ^^^^^ +>fn : (a: string, b: T) => unknown +> : ^ ^^ ^^ ^^ ^^^^^ +>a : string +> : ^^^^^^ +>b : T +> : ^ +>b : T +> : ^ + +declare function fn( +>fn : (fn: (...args: Args) => unknown) => (...args: Args) => unknown +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^ + + fn: (...args: Args) => unknown, +>fn : (...args: Args) => unknown +> : ^^^^ ^^ ^^^^^ +>args : Args +> : ^^^^ + +): (...args: Args) => unknown; +>args : Args +> : ^^^^ + +call( +>call( fn(function (a, b: number) { a; // string }),) : (b: number) => unknown +> : ^ ^^^^^^^^^^^^^ +>call : (fn: (a: string, b: T) => unknown) => (b: T) => unknown +> : ^ ^^ ^^ ^^^^^ + + fn(function (a, b: number) { +>fn(function (a, b: number) { a; // string }) : (a: string, b: number) => unknown +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^ +>fn : (fn: (...args: Args) => unknown) => (...args: Args) => unknown +> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^ +>function (a, b: number) { a; // string } : (a: string, b: number) => void +> : ^ ^^^^^^^^^^ ^^ ^^^^^^^^^ +>a : string +> : ^^^^^^ +>b : number +> : ^^^^^^ + + a; // string +>a : string +> : ^^^^^^ + + }), +); + diff --git a/tests/cases/compiler/contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts b/tests/cases/compiler/contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts new file mode 100644 index 0000000000000..58e1c33818cfc --- /dev/null +++ b/tests/cases/compiler/contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts @@ -0,0 +1,16 @@ +// @strict: true +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/62336 + +declare function call(fn: (a: string, b: T) => unknown): (b: T) => unknown; + +declare function fn( + fn: (...args: Args) => unknown, +): (...args: Args) => unknown; + +call( + fn(function (a, b: number) { + a; // string + }), +); From 37499a83cc31dbdaac8a4a581b7771829b6b58cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Wed, 27 Aug 2025 10:53:36 +0200 Subject: [PATCH 2/2] fix filename typo --- ...singInstantiantedRestReturnMapper1.symbols | 42 ------------------- ...UsingInstantiatedRestReturnMapper1.symbols | 42 +++++++++++++++++++ ...sUsingInstantiatedRestReturnMapper1.types} | 4 +- ...tersUsingInstantiatedRestReturnMapper1.ts} | 0 4 files changed, 44 insertions(+), 44 deletions(-) delete mode 100644 tests/baselines/reference/contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.symbols create mode 100644 tests/baselines/reference/contextuallyTypeParametersUsingInstantiatedRestReturnMapper1.symbols rename tests/baselines/reference/{contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.types => contextuallyTypeParametersUsingInstantiatedRestReturnMapper1.types} (91%) rename tests/cases/compiler/{contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts => contextuallyTypeParametersUsingInstantiatedRestReturnMapper1.ts} (100%) diff --git a/tests/baselines/reference/contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.symbols b/tests/baselines/reference/contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.symbols deleted file mode 100644 index 63906fbf313c2..0000000000000 --- a/tests/baselines/reference/contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.symbols +++ /dev/null @@ -1,42 +0,0 @@ -//// [tests/cases/compiler/contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts] //// - -=== contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts === -// https://github.com/microsoft/TypeScript/issues/62336 - -declare function call(fn: (a: string, b: T) => unknown): (b: T) => unknown; ->call : Symbol(call, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 0, 0)) ->T : Symbol(T, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 2, 22)) ->fn : Symbol(fn, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 2, 25)) ->a : Symbol(a, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 2, 30)) ->b : Symbol(b, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 2, 40)) ->T : Symbol(T, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 2, 22)) ->b : Symbol(b, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 2, 61)) ->T : Symbol(T, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 2, 22)) - -declare function fn( ->fn : Symbol(fn, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 2, 78)) ->Args : Symbol(Args, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 4, 20)) - - fn: (...args: Args) => unknown, ->fn : Symbol(fn, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 4, 40)) ->args : Symbol(args, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 5, 7)) ->Args : Symbol(Args, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 4, 20)) - -): (...args: Args) => unknown; ->args : Symbol(args, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 6, 4)) ->Args : Symbol(Args, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 4, 20)) - -call( ->call : Symbol(call, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 0, 0)) - - fn(function (a, b: number) { ->fn : Symbol(fn, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 2, 78)) ->a : Symbol(a, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 9, 15)) ->b : Symbol(b, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 9, 17)) - - a; // string ->a : Symbol(a, Decl(contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts, 9, 15)) - - }), -); - diff --git a/tests/baselines/reference/contextuallyTypeParametersUsingInstantiatedRestReturnMapper1.symbols b/tests/baselines/reference/contextuallyTypeParametersUsingInstantiatedRestReturnMapper1.symbols new file mode 100644 index 0000000000000..d95517b598ee9 --- /dev/null +++ b/tests/baselines/reference/contextuallyTypeParametersUsingInstantiatedRestReturnMapper1.symbols @@ -0,0 +1,42 @@ +//// [tests/cases/compiler/contextuallyTypeParametersUsingInstantiatedRestReturnMapper1.ts] //// + +=== contextuallyTypeParametersUsingInstantiatedRestReturnMapper1.ts === +// https://github.com/microsoft/TypeScript/issues/62336 + +declare function call(fn: (a: string, b: T) => unknown): (b: T) => unknown; +>call : Symbol(call, Decl(contextuallyTypeParametersUsingInstantiatedRestReturnMapper1.ts, 0, 0)) +>T : Symbol(T, Decl(contextuallyTypeParametersUsingInstantiatedRestReturnMapper1.ts, 2, 22)) +>fn : Symbol(fn, Decl(contextuallyTypeParametersUsingInstantiatedRestReturnMapper1.ts, 2, 25)) +>a : Symbol(a, Decl(contextuallyTypeParametersUsingInstantiatedRestReturnMapper1.ts, 2, 30)) +>b : Symbol(b, Decl(contextuallyTypeParametersUsingInstantiatedRestReturnMapper1.ts, 2, 40)) +>T : Symbol(T, Decl(contextuallyTypeParametersUsingInstantiatedRestReturnMapper1.ts, 2, 22)) +>b : Symbol(b, Decl(contextuallyTypeParametersUsingInstantiatedRestReturnMapper1.ts, 2, 61)) +>T : Symbol(T, Decl(contextuallyTypeParametersUsingInstantiatedRestReturnMapper1.ts, 2, 22)) + +declare function fn( +>fn : Symbol(fn, Decl(contextuallyTypeParametersUsingInstantiatedRestReturnMapper1.ts, 2, 78)) +>Args : Symbol(Args, Decl(contextuallyTypeParametersUsingInstantiatedRestReturnMapper1.ts, 4, 20)) + + fn: (...args: Args) => unknown, +>fn : Symbol(fn, Decl(contextuallyTypeParametersUsingInstantiatedRestReturnMapper1.ts, 4, 40)) +>args : Symbol(args, Decl(contextuallyTypeParametersUsingInstantiatedRestReturnMapper1.ts, 5, 7)) +>Args : Symbol(Args, Decl(contextuallyTypeParametersUsingInstantiatedRestReturnMapper1.ts, 4, 20)) + +): (...args: Args) => unknown; +>args : Symbol(args, Decl(contextuallyTypeParametersUsingInstantiatedRestReturnMapper1.ts, 6, 4)) +>Args : Symbol(Args, Decl(contextuallyTypeParametersUsingInstantiatedRestReturnMapper1.ts, 4, 20)) + +call( +>call : Symbol(call, Decl(contextuallyTypeParametersUsingInstantiatedRestReturnMapper1.ts, 0, 0)) + + fn(function (a, b: number) { +>fn : Symbol(fn, Decl(contextuallyTypeParametersUsingInstantiatedRestReturnMapper1.ts, 2, 78)) +>a : Symbol(a, Decl(contextuallyTypeParametersUsingInstantiatedRestReturnMapper1.ts, 9, 15)) +>b : Symbol(b, Decl(contextuallyTypeParametersUsingInstantiatedRestReturnMapper1.ts, 9, 17)) + + a; // string +>a : Symbol(a, Decl(contextuallyTypeParametersUsingInstantiatedRestReturnMapper1.ts, 9, 15)) + + }), +); + diff --git a/tests/baselines/reference/contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.types b/tests/baselines/reference/contextuallyTypeParametersUsingInstantiatedRestReturnMapper1.types similarity index 91% rename from tests/baselines/reference/contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.types rename to tests/baselines/reference/contextuallyTypeParametersUsingInstantiatedRestReturnMapper1.types index 9e95864076857..4d17d78212398 100644 --- a/tests/baselines/reference/contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.types +++ b/tests/baselines/reference/contextuallyTypeParametersUsingInstantiatedRestReturnMapper1.types @@ -1,6 +1,6 @@ -//// [tests/cases/compiler/contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts] //// +//// [tests/cases/compiler/contextuallyTypeParametersUsingInstantiatedRestReturnMapper1.ts] //// -=== contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts === +=== contextuallyTypeParametersUsingInstantiatedRestReturnMapper1.ts === // https://github.com/microsoft/TypeScript/issues/62336 declare function call(fn: (a: string, b: T) => unknown): (b: T) => unknown; diff --git a/tests/cases/compiler/contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts b/tests/cases/compiler/contextuallyTypeParametersUsingInstantiatedRestReturnMapper1.ts similarity index 100% rename from tests/cases/compiler/contextuallyTypeParametersUsingInstantiantedRestReturnMapper1.ts rename to tests/cases/compiler/contextuallyTypeParametersUsingInstantiatedRestReturnMapper1.ts