diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index aec962016a2..5e7695ffef3 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -586,6 +586,9 @@ namespace ts { } function jsdocTreatAsExported(node: Node) { + if (node.parent && isModuleDeclaration(node)) { + node = node.parent; + } if (!isJSDocTypeAlias(node)) return false; // jsdoc typedef handling is a bit of a doozy, but to summarize, treat the typedef as exported if: // 1. It has an explicit name (since by default typedefs are always directly exported, either at the top level or in a container), or diff --git a/tests/baselines/reference/jsDeclarationsImportAliasExposedWithinNamespace.js b/tests/baselines/reference/jsDeclarationsImportAliasExposedWithinNamespace.js index d4022eb9ed9..22ac1176448 100644 --- a/tests/baselines/reference/jsDeclarationsImportAliasExposedWithinNamespace.js +++ b/tests/baselines/reference/jsDeclarationsImportAliasExposedWithinNamespace.js @@ -54,14 +54,6 @@ export {testFn, testFnTypes}; //// [file.d.ts] -/** - * @namespace myTypes - * @global - * @type {Object} - */ -export const myTypes: { - [x: string]: any; -}; export namespace myTypes { type typeA = string | RegExp | (string | RegExp)[]; type typeB = { @@ -76,7 +68,18 @@ export namespace myTypes { }; type typeC = Function | typeB; } +/** + * @namespace myTypes + * @global + * @type {Object} + */ +export const myTypes: { + [x: string]: any; +}; //// [file2.d.ts] +export namespace testFnTypes { + type input = boolean | Function | myTypes.typeB; +} /** @typedef {boolean|myTypes.typeC} testFnTypes.input */ /** * @function testFn @@ -85,6 +88,7 @@ export namespace myTypes { * @returns {number|null} Result. */ export function testFn(input: testFnTypes.input): number | null; +import { myTypes } from "./file.js"; /** * @namespace testFnTypes * @global @@ -93,7 +97,3 @@ export function testFn(input: testFnTypes.input): number | null; export const testFnTypes: { [x: string]: any; }; -export namespace testFnTypes { - type input = boolean | Function | myTypes.typeB; -} -import { myTypes } from "./file.js"; diff --git a/tests/baselines/reference/jsDeclarationsImportAliasExposedWithinNamespace.symbols b/tests/baselines/reference/jsDeclarationsImportAliasExposedWithinNamespace.symbols index c12e398c008..4fb1a34c87b 100644 --- a/tests/baselines/reference/jsDeclarationsImportAliasExposedWithinNamespace.symbols +++ b/tests/baselines/reference/jsDeclarationsImportAliasExposedWithinNamespace.symbols @@ -21,7 +21,7 @@ const myTypes = { /** @typedef {myTypes.typeB|Function} myTypes.typeC */ export {myTypes}; ->myTypes : Symbol(myTypes, Decl(file.js, 19, 8)) +>myTypes : Symbol(myTypes, Decl(file.js, 19, 8), Decl(file.js, 9, 50), Decl(file.js, 12, 12), Decl(file.js, 17, 38)) === tests/cases/conformance/jsdoc/declarations/file2.js === import {myTypes} from './file.js'; @@ -63,5 +63,5 @@ function testFn(input) { export {testFn, testFnTypes}; >testFn : Symbol(testFn, Decl(file2.js, 27, 8)) ->testFnTypes : Symbol(testFnTypes, Decl(file2.js, 27, 15)) +>testFnTypes : Symbol(testFnTypes, Decl(file2.js, 27, 15), Decl(file2.js, 11, 37)) diff --git a/tests/baselines/reference/jsDeclarationsImportAliasExposedWithinNamespace.types b/tests/baselines/reference/jsDeclarationsImportAliasExposedWithinNamespace.types index f1ce40fe833..28424f9792b 100644 --- a/tests/baselines/reference/jsDeclarationsImportAliasExposedWithinNamespace.types +++ b/tests/baselines/reference/jsDeclarationsImportAliasExposedWithinNamespace.types @@ -26,7 +26,7 @@ export {myTypes}; === tests/cases/conformance/jsdoc/declarations/file2.js === import {myTypes} from './file.js'; ->myTypes : { [x: string]: any; } +>myTypes : any /** * @namespace testFnTypes @@ -50,12 +50,12 @@ const testFnTypes = { */ function testFn(input) { >testFn : (input: testFnTypes.input) => number | null ->input : boolean | Function | myTypes.typeB +>input : import("tests/cases/conformance/jsdoc/declarations/file2").testFnTypes.input if (typeof input === 'number') { >typeof input === 'number' : boolean >typeof input : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" ->input : boolean | Function | myTypes.typeB +>input : import("tests/cases/conformance/jsdoc/declarations/file2").testFnTypes.input >'number' : "number" return 2 * input; diff --git a/tests/baselines/reference/jsDeclarationsImportNamespacedType.js b/tests/baselines/reference/jsDeclarationsImportNamespacedType.js new file mode 100644 index 00000000000..a044630e9a9 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsImportNamespacedType.js @@ -0,0 +1,22 @@ +//// [tests/cases/conformance/jsdoc/declarations/jsDeclarationsImportNamespacedType.ts] //// + +//// [file.js] +import { dummy } from './mod1' +/** @type {import('./mod1').Dotted.Name} - should work */ +var dot2 + +//// [mod1.js] +/** @typedef {number} Dotted.Name */ +export var dummy = 1 + + + + +//// [mod1.d.ts] +/** @typedef {number} Dotted.Name */ +export var dummy: number; +export namespace Dotted { + type Name = number; +} +//// [file.d.ts] +export {}; diff --git a/tests/baselines/reference/jsDeclarationsImportNamespacedType.symbols b/tests/baselines/reference/jsDeclarationsImportNamespacedType.symbols new file mode 100644 index 00000000000..491a4a261e7 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsImportNamespacedType.symbols @@ -0,0 +1,13 @@ +=== tests/cases/conformance/jsdoc/declarations/file.js === +import { dummy } from './mod1' +>dummy : Symbol(dummy, Decl(file.js, 0, 8)) + +/** @type {import('./mod1').Dotted.Name} - should work */ +var dot2 +>dot2 : Symbol(dot2, Decl(file.js, 2, 3)) + +=== tests/cases/conformance/jsdoc/declarations/mod1.js === +/** @typedef {number} Dotted.Name */ +export var dummy = 1 +>dummy : Symbol(dummy, Decl(mod1.js, 1, 10)) + diff --git a/tests/baselines/reference/jsDeclarationsImportNamespacedType.types b/tests/baselines/reference/jsDeclarationsImportNamespacedType.types new file mode 100644 index 00000000000..4840d53ab81 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsImportNamespacedType.types @@ -0,0 +1,14 @@ +=== tests/cases/conformance/jsdoc/declarations/file.js === +import { dummy } from './mod1' +>dummy : number + +/** @type {import('./mod1').Dotted.Name} - should work */ +var dot2 +>dot2 : number + +=== tests/cases/conformance/jsdoc/declarations/mod1.js === +/** @typedef {number} Dotted.Name */ +export var dummy = 1 +>dummy : number +>1 : 1 + diff --git a/tests/cases/conformance/jsdoc/declarations/jsDeclarationsImportNamespacedType.ts b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsImportNamespacedType.ts new file mode 100644 index 00000000000..799978bbbf6 --- /dev/null +++ b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsImportNamespacedType.ts @@ -0,0 +1,11 @@ +// @declaration: true +// @emitDeclarationOnly: true +// @checkJs: true +// @filename: file.js +import { dummy } from './mod1' +/** @type {import('./mod1').Dotted.Name} - should work */ +var dot2 + +// @filename: mod1.js +/** @typedef {number} Dotted.Name */ +export var dummy = 1