diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index c61581facde83..aa87ed7e7343d 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -35379,6 +35379,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
assignNonContextualParameterTypes(signature);
}
}
+ else if (contextualSignature && !node.typeParameters && contextualSignature.parameters.length > node.parameters.length) {
+ const inferenceContext = getInferenceContext(node);
+ if (checkMode && checkMode & CheckMode.Inferential) {
+ inferFromAnnotatedParameters(signature, contextualSignature, inferenceContext!);
+ }
+ }
if (contextualSignature && !getReturnTypeFromAnnotation(node) && !signature.resolvedReturnType) {
const returnType = getReturnTypeFromBody(node, checkMode);
if (!signature.resolvedReturnType) {
diff --git a/tests/baselines/reference/contravariantOnlyInferenceFromAnnotatedFunction.symbols b/tests/baselines/reference/contravariantOnlyInferenceFromAnnotatedFunction.symbols
new file mode 100644
index 0000000000000..a0312fa3daf79
--- /dev/null
+++ b/tests/baselines/reference/contravariantOnlyInferenceFromAnnotatedFunction.symbols
@@ -0,0 +1,57 @@
+=== tests/cases/compiler/contravariantOnlyInferenceFromAnnotatedFunction.ts ===
+// repro from #52580
+
+type Funcs> = {
+>Funcs : Symbol(Funcs, Decl(contravariantOnlyInferenceFromAnnotatedFunction.ts, 0, 0))
+>A : Symbol(A, Decl(contravariantOnlyInferenceFromAnnotatedFunction.ts, 2, 11))
+>B : Symbol(B, Decl(contravariantOnlyInferenceFromAnnotatedFunction.ts, 2, 13))
+>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
+
+ [K in keyof B]: {
+>K : Symbol(K, Decl(contravariantOnlyInferenceFromAnnotatedFunction.ts, 3, 3))
+>B : Symbol(B, Decl(contravariantOnlyInferenceFromAnnotatedFunction.ts, 2, 13))
+
+ fn: (a: A, b: B) => void;
+>fn : Symbol(fn, Decl(contravariantOnlyInferenceFromAnnotatedFunction.ts, 3, 19))
+>a : Symbol(a, Decl(contravariantOnlyInferenceFromAnnotatedFunction.ts, 4, 9))
+>A : Symbol(A, Decl(contravariantOnlyInferenceFromAnnotatedFunction.ts, 2, 11))
+>b : Symbol(b, Decl(contravariantOnlyInferenceFromAnnotatedFunction.ts, 4, 14))
+>B : Symbol(B, Decl(contravariantOnlyInferenceFromAnnotatedFunction.ts, 2, 13))
+
+ thing: B[K];
+>thing : Symbol(thing, Decl(contravariantOnlyInferenceFromAnnotatedFunction.ts, 4, 29))
+>B : Symbol(B, Decl(contravariantOnlyInferenceFromAnnotatedFunction.ts, 2, 13))
+>K : Symbol(K, Decl(contravariantOnlyInferenceFromAnnotatedFunction.ts, 3, 3))
+
+ };
+}
+
+declare function foo>(fns: Funcs): [A, B]
+>foo : Symbol(foo, Decl(contravariantOnlyInferenceFromAnnotatedFunction.ts, 7, 1))
+>A : Symbol(A, Decl(contravariantOnlyInferenceFromAnnotatedFunction.ts, 9, 21))
+>B : Symbol(B, Decl(contravariantOnlyInferenceFromAnnotatedFunction.ts, 9, 23))
+>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
+>fns : Symbol(fns, Decl(contravariantOnlyInferenceFromAnnotatedFunction.ts, 9, 59))
+>Funcs : Symbol(Funcs, Decl(contravariantOnlyInferenceFromAnnotatedFunction.ts, 0, 0))
+>A : Symbol(A, Decl(contravariantOnlyInferenceFromAnnotatedFunction.ts, 9, 21))
+>B : Symbol(B, Decl(contravariantOnlyInferenceFromAnnotatedFunction.ts, 9, 23))
+>A : Symbol(A, Decl(contravariantOnlyInferenceFromAnnotatedFunction.ts, 9, 21))
+>B : Symbol(B, Decl(contravariantOnlyInferenceFromAnnotatedFunction.ts, 9, 23))
+
+const result = foo({
+>result : Symbol(result, Decl(contravariantOnlyInferenceFromAnnotatedFunction.ts, 11, 5))
+>foo : Symbol(foo, Decl(contravariantOnlyInferenceFromAnnotatedFunction.ts, 7, 1))
+
+ bar: {
+>bar : Symbol(bar, Decl(contravariantOnlyInferenceFromAnnotatedFunction.ts, 11, 20))
+
+ fn: (a: string) => {},
+>fn : Symbol(fn, Decl(contravariantOnlyInferenceFromAnnotatedFunction.ts, 12, 8))
+>a : Symbol(a, Decl(contravariantOnlyInferenceFromAnnotatedFunction.ts, 13, 9))
+
+ thing: 'asd',
+>thing : Symbol(thing, Decl(contravariantOnlyInferenceFromAnnotatedFunction.ts, 13, 26))
+
+ },
+});
+
diff --git a/tests/baselines/reference/contravariantOnlyInferenceFromAnnotatedFunction.types b/tests/baselines/reference/contravariantOnlyInferenceFromAnnotatedFunction.types
new file mode 100644
index 0000000000000..2f7f5b561ae97
--- /dev/null
+++ b/tests/baselines/reference/contravariantOnlyInferenceFromAnnotatedFunction.types
@@ -0,0 +1,44 @@
+=== tests/cases/compiler/contravariantOnlyInferenceFromAnnotatedFunction.ts ===
+// repro from #52580
+
+type Funcs> = {
+>Funcs : Funcs
+
+ [K in keyof B]: {
+ fn: (a: A, b: B) => void;
+>fn : (a: A, b: B) => void
+>a : A
+>b : B
+
+ thing: B[K];
+>thing : B[K]
+
+ };
+}
+
+declare function foo>(fns: Funcs): [A, B]
+>foo : >(fns: Funcs) => [A, B]
+>fns : Funcs
+
+const result = foo({
+>result : [string, { bar: string; }]
+>foo({ bar: { fn: (a: string) => {}, thing: 'asd', },}) : [string, { bar: string; }]
+>foo : >(fns: Funcs) => [A, B]
+>{ bar: { fn: (a: string) => {}, thing: 'asd', },} : { bar: { fn: (a: string) => void; thing: string; }; }
+
+ bar: {
+>bar : { fn: (a: string) => void; thing: string; }
+>{ fn: (a: string) => {}, thing: 'asd', } : { fn: (a: string) => void; thing: string; }
+
+ fn: (a: string) => {},
+>fn : (a: string) => void
+>(a: string) => {} : (a: string) => void
+>a : string
+
+ thing: 'asd',
+>thing : string
+>'asd' : "asd"
+
+ },
+});
+
diff --git a/tests/cases/compiler/contravariantOnlyInferenceFromAnnotatedFunction.ts b/tests/cases/compiler/contravariantOnlyInferenceFromAnnotatedFunction.ts
new file mode 100644
index 0000000000000..c3b1fd9115ab0
--- /dev/null
+++ b/tests/cases/compiler/contravariantOnlyInferenceFromAnnotatedFunction.ts
@@ -0,0 +1,20 @@
+// @strict: true
+// @noEmit: true
+
+// repro from #52580
+
+type Funcs> = {
+ [K in keyof B]: {
+ fn: (a: A, b: B) => void;
+ thing: B[K];
+ };
+}
+
+declare function foo>(fns: Funcs): [A, B]
+
+const result = foo({
+ bar: {
+ fn: (a: string) => {},
+ thing: 'asd',
+ },
+});