Skip to content

Fix export binding of namespaced typedefs #40980

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/compiler/binder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,6 @@ export {testFn, testFnTypes};


//// [file.d.ts]
/**
* @namespace myTypes
* @global
* @type {Object<string,*>}
*/
export const myTypes: {
[x: string]: any;
};
export namespace myTypes {
type typeA = string | RegExp | (string | RegExp)[];
type typeB = {
Expand All @@ -76,7 +68,18 @@ export namespace myTypes {
};
type typeC = Function | typeB;
}
/**
* @namespace myTypes
* @global
* @type {Object<string,*>}
*/
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
Expand All @@ -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
Expand All @@ -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";
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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))

Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
Expand Down
22 changes: 22 additions & 0 deletions tests/baselines/reference/jsDeclarationsImportNamespacedType.js
Original file line number Diff line number Diff line change
@@ -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 {};
Original file line number Diff line number Diff line change
@@ -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))

14 changes: 14 additions & 0 deletions tests/baselines/reference/jsDeclarationsImportNamespacedType.types
Original file line number Diff line number Diff line change
@@ -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

Original file line number Diff line number Diff line change
@@ -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