From 418494e4c4fa1386b20452dbbab31293c5e13049 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Tue, 29 Aug 2023 01:02:52 +0200 Subject: [PATCH] Infer from parameters annotated using JSDoc (#55400) --- src/compiler/checker.ts | 12 ++--- ...lyInferenceFromAnnotatedFunctionJs.symbols | 41 ++++++++++++++++ ...OnlyInferenceFromAnnotatedFunctionJs.types | 47 +++++++++++++++++++ ...antOnlyInferenceFromAnnotatedFunctionJs.ts | 30 ++++++++++++ 4 files changed, 123 insertions(+), 7 deletions(-) create mode 100644 tests/baselines/reference/contravariantOnlyInferenceFromAnnotatedFunctionJs.symbols create mode 100644 tests/baselines/reference/contravariantOnlyInferenceFromAnnotatedFunctionJs.types create mode 100644 tests/cases/compiler/contravariantOnlyInferenceFromAnnotatedFunctionJs.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c210618580c..cfa558f05fa 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -35600,13 +35600,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const len = signature.parameters.length - (signatureHasRestParameter(signature) ? 1 : 0); for (let i = 0; i < len; i++) { const declaration = signature.parameters[i].valueDeclaration as ParameterDeclaration; - if (declaration.type) { - const typeNode = getEffectiveTypeAnnotationNode(declaration); - if (typeNode) { - const source = addOptionality(getTypeFromTypeNode(typeNode), /*isProperty*/ false, isOptionalDeclaration(declaration)); - const target = getTypeAtPosition(context, i); - inferTypes(inferenceContext.inferences, source, target); - } + const typeNode = getEffectiveTypeAnnotationNode(declaration); + if (typeNode) { + const source = addOptionality(getTypeFromTypeNode(typeNode), /*isProperty*/ false, isOptionalDeclaration(declaration)); + const target = getTypeAtPosition(context, i); + inferTypes(inferenceContext.inferences, source, target); } } } diff --git a/tests/baselines/reference/contravariantOnlyInferenceFromAnnotatedFunctionJs.symbols b/tests/baselines/reference/contravariantOnlyInferenceFromAnnotatedFunctionJs.symbols new file mode 100644 index 00000000000..447299b80a9 --- /dev/null +++ b/tests/baselines/reference/contravariantOnlyInferenceFromAnnotatedFunctionJs.symbols @@ -0,0 +1,41 @@ +//// [tests/cases/compiler/contravariantOnlyInferenceFromAnnotatedFunctionJs.ts] //// + +=== index.js === +/** + * @typedef {{ [K in keyof B]: { fn: (a: A, b: B) => void; thing: B[K]; } }} Funcs + * @template A + * @template {Record} B + */ + +/** + * @template A + * @template {Record} B + * @param {Funcs} fns + * @returns {[A, B]} + */ +function foo(fns) { +>foo : Symbol(foo, Decl(index.js, 0, 0)) +>fns : Symbol(fns, Decl(index.js, 12, 13)) + + return /** @type {any} */ (null); +} + +const result = foo({ +>result : Symbol(result, Decl(index.js, 16, 5)) +>foo : Symbol(foo, Decl(index.js, 0, 0)) + + bar: { +>bar : Symbol(bar, Decl(index.js, 16, 20)) + + fn: +>fn : Symbol(fn, Decl(index.js, 17, 8)) + + /** @param {string} a */ + (a) => {}, +>a : Symbol(a, Decl(index.js, 20, 7)) + + thing: "asd", +>thing : Symbol(thing, Decl(index.js, 20, 16)) + + }, +}); diff --git a/tests/baselines/reference/contravariantOnlyInferenceFromAnnotatedFunctionJs.types b/tests/baselines/reference/contravariantOnlyInferenceFromAnnotatedFunctionJs.types new file mode 100644 index 00000000000..2f4658db577 --- /dev/null +++ b/tests/baselines/reference/contravariantOnlyInferenceFromAnnotatedFunctionJs.types @@ -0,0 +1,47 @@ +//// [tests/cases/compiler/contravariantOnlyInferenceFromAnnotatedFunctionJs.ts] //// + +=== index.js === +/** + * @typedef {{ [K in keyof B]: { fn: (a: A, b: B) => void; thing: B[K]; } }} Funcs + * @template A + * @template {Record} B + */ + +/** + * @template A + * @template {Record} B + * @param {Funcs} fns + * @returns {[A, B]} + */ +function foo(fns) { +>foo : >(fns: Funcs) => [A, B] +>fns : Funcs + + return /** @type {any} */ (null); +>(null) : any +} + +const result = foo({ +>result : [string, { bar: string; }] +>foo({ bar: { fn: /** @param {string} a */ (a) => {}, thing: "asd", },}) : [string, { bar: string; }] +>foo : >(fns: Funcs) => [A, B] +>{ bar: { fn: /** @param {string} a */ (a) => {}, thing: "asd", },} : { bar: { fn: (a: string) => void; thing: string; }; } + + bar: { +>bar : { fn: (a: string) => void; thing: string; } +>{ fn: /** @param {string} a */ (a) => {}, thing: "asd", } : { fn: (a: string) => void; thing: string; } + + fn: +>fn : (a: string) => void + + /** @param {string} a */ + (a) => {}, +>(a) => {} : (a: string) => void +>a : string + + thing: "asd", +>thing : string +>"asd" : "asd" + + }, +}); diff --git a/tests/cases/compiler/contravariantOnlyInferenceFromAnnotatedFunctionJs.ts b/tests/cases/compiler/contravariantOnlyInferenceFromAnnotatedFunctionJs.ts new file mode 100644 index 00000000000..5d556894ea3 --- /dev/null +++ b/tests/cases/compiler/contravariantOnlyInferenceFromAnnotatedFunctionJs.ts @@ -0,0 +1,30 @@ +// @strict: true +// @checkJs: true +// @noEmit: true + +// @filename: index.js + +/** + * @typedef {{ [K in keyof B]: { fn: (a: A, b: B) => void; thing: B[K]; } }} Funcs + * @template A + * @template {Record} B + */ + +/** + * @template A + * @template {Record} B + * @param {Funcs} fns + * @returns {[A, B]} + */ +function foo(fns) { + return /** @type {any} */ (null); +} + +const result = foo({ + bar: { + fn: + /** @param {string} a */ + (a) => {}, + thing: "asd", + }, +}); \ No newline at end of file