mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-15 12:51:30 -05:00
Fix export binding of namespaced typedefs (#40980)
The binder incorrectly rejected implicit namespace declarations in typedefs.
This commit is contained in:
committed by
GitHub
parent
4dc7e59248
commit
4283428906
@@ -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
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {};
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user