Fix export binding of namespaced typedefs (#40980)

The binder incorrectly rejected implicit namespace declarations in
typedefs.
This commit is contained in:
Nathan Shively-Sanders
2020-10-07 13:21:02 -07:00
committed by GitHub
parent 4dc7e59248
commit 4283428906
8 changed files with 80 additions and 17 deletions

View File

@@ -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

View File

@@ -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 = {
@@ -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
@@ -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";

View File

@@ -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))

View File

@@ -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;

View File

@@ -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 {};

View File

@@ -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))

View File

@@ -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

View File

@@ -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