diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f4ee7960f1074..d5819950bf24c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -30345,7 +30345,14 @@ namespace ts { } function assignContextualParameterTypes(signature: Signature, context: Signature) { - signature.typeParameters = context.typeParameters; + if (context.typeParameters) { + if (!signature.typeParameters) { + signature.typeParameters = context.typeParameters; + } + else { + return; // This signature has already has a contextual inference performed and cached on it! + } + } if (context.thisParameter) { const parameter = signature.thisParameter; if (!parameter || parameter.valueDeclaration && !(parameter.valueDeclaration).type) { diff --git a/tests/baselines/reference/contextuallyTypedGenericAssignment.js b/tests/baselines/reference/contextuallyTypedGenericAssignment.js new file mode 100644 index 0000000000000..c574f08e4c3ee --- /dev/null +++ b/tests/baselines/reference/contextuallyTypedGenericAssignment.js @@ -0,0 +1,10 @@ +//// [contextuallyTypedGenericAssignment.ts] +function foo( + arg: (t: T, ...rest: A) => number +) { } + +foo((t, u: number) => t.a) + +//// [contextuallyTypedGenericAssignment.js] +function foo(arg) { } +foo(function (t, u) { return t.a; }); diff --git a/tests/baselines/reference/contextuallyTypedGenericAssignment.symbols b/tests/baselines/reference/contextuallyTypedGenericAssignment.symbols new file mode 100644 index 0000000000000..ccdd9f36fba84 --- /dev/null +++ b/tests/baselines/reference/contextuallyTypedGenericAssignment.symbols @@ -0,0 +1,24 @@ +=== tests/cases/compiler/contextuallyTypedGenericAssignment.ts === +function foo( +>foo : Symbol(foo, Decl(contextuallyTypedGenericAssignment.ts, 0, 0)) +>A : Symbol(A, Decl(contextuallyTypedGenericAssignment.ts, 0, 13)) + + arg: (t: T, ...rest: A) => number +>arg : Symbol(arg, Decl(contextuallyTypedGenericAssignment.ts, 0, 30)) +>T : Symbol(T, Decl(contextuallyTypedGenericAssignment.ts, 1, 10)) +>a : Symbol(a, Decl(contextuallyTypedGenericAssignment.ts, 1, 21)) +>t : Symbol(t, Decl(contextuallyTypedGenericAssignment.ts, 1, 35)) +>T : Symbol(T, Decl(contextuallyTypedGenericAssignment.ts, 1, 10)) +>rest : Symbol(rest, Decl(contextuallyTypedGenericAssignment.ts, 1, 40)) +>A : Symbol(A, Decl(contextuallyTypedGenericAssignment.ts, 0, 13)) + +) { } + +foo((t, u: number) => t.a) +>foo : Symbol(foo, Decl(contextuallyTypedGenericAssignment.ts, 0, 0)) +>t : Symbol(t, Decl(contextuallyTypedGenericAssignment.ts, 4, 5)) +>u : Symbol(u, Decl(contextuallyTypedGenericAssignment.ts, 4, 7)) +>t.a : Symbol(a, Decl(contextuallyTypedGenericAssignment.ts, 1, 21)) +>t : Symbol(t, Decl(contextuallyTypedGenericAssignment.ts, 4, 5)) +>a : Symbol(a, Decl(contextuallyTypedGenericAssignment.ts, 1, 21)) + diff --git a/tests/baselines/reference/contextuallyTypedGenericAssignment.types b/tests/baselines/reference/contextuallyTypedGenericAssignment.types new file mode 100644 index 0000000000000..6c58467bc56cc --- /dev/null +++ b/tests/baselines/reference/contextuallyTypedGenericAssignment.types @@ -0,0 +1,22 @@ +=== tests/cases/compiler/contextuallyTypedGenericAssignment.ts === +function foo( +>foo : (arg: (t: T, ...rest: A) => number) => void + + arg: (t: T, ...rest: A) => number +>arg : (t: T, ...rest: A) => number +>a : number +>t : T +>rest : A + +) { } + +foo((t, u: number) => t.a) +>foo((t, u: number) => t.a) : void +>foo : (arg: (t: T, ...rest: A) => number) => void +>(t, u: number) => t.a : (t: T, u: number) => number +>t : T +>u : number +>t.a : number +>t : T +>a : number + diff --git a/tests/cases/compiler/contextuallyTypedGenericAssignment.ts b/tests/cases/compiler/contextuallyTypedGenericAssignment.ts new file mode 100644 index 0000000000000..1ce7258b787ef --- /dev/null +++ b/tests/cases/compiler/contextuallyTypedGenericAssignment.ts @@ -0,0 +1,5 @@ +function foo( + arg: (t: T, ...rest: A) => number +) { } + +foo((t, u: number) => t.a) \ No newline at end of file