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', + }, +});