From 809df94234612e4dcbe1287cf469d029fbdc357f Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Fri, 7 Aug 2020 16:23:32 -0400 Subject: [PATCH] Avoid the double symbol for names that are explicitly exported Fixes #33575. --- src/compiler/binder.ts | 17 +++++++++-- .../valueAndType_ExportAs-default.symbols | 19 ++++++++++++ .../valueAndType_ExportAs-default.types | 23 +++++++++++++++ .../reference/valueAndType_ExportAs.symbols | 19 ++++++++++++ .../reference/valueAndType_ExportAs.types | 23 +++++++++++++++ .../valueAndType_ExportDefault-enum.symbols | 26 +++++++++++++++++ .../valueAndType_ExportDefault-enum.types | 29 +++++++++++++++++++ .../valueAndType_ExportDefault.symbols | 18 ++++++++++++ .../valueAndType_ExportDefault.types | 22 ++++++++++++++ .../valueAndType_ExportDestructure.symbols | 18 ++++++++++++ .../valueAndType_ExportDestructure.types | 24 +++++++++++++++ .../reference/valueAndType_ExportLet.symbols | 15 ++++++++++ .../reference/valueAndType_ExportLet.types | 19 ++++++++++++ .../valueAndType_ModuleExports.symbols | 23 +++++++++++++++ .../valueAndType_ModuleExports.types | 29 +++++++++++++++++++ .../jsdoc/valueAndType_ExportAs-default.ts | 14 +++++++++ .../jsdoc/valueAndType_ExportAs.ts | 14 +++++++++ .../jsdoc/valueAndType_ExportDefault-enum.ts | 17 +++++++++++ .../jsdoc/valueAndType_ExportDefault.ts | 14 +++++++++ .../jsdoc/valueAndType_ExportDestructure.ts | 13 +++++++++ .../jsdoc/valueAndType_ExportLet.ts | 13 +++++++++ .../jsdoc/valueAndType_ModuleExports.ts | 14 +++++++++ 22 files changed, 421 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/valueAndType_ExportAs-default.symbols create mode 100644 tests/baselines/reference/valueAndType_ExportAs-default.types create mode 100644 tests/baselines/reference/valueAndType_ExportAs.symbols create mode 100644 tests/baselines/reference/valueAndType_ExportAs.types create mode 100644 tests/baselines/reference/valueAndType_ExportDefault-enum.symbols create mode 100644 tests/baselines/reference/valueAndType_ExportDefault-enum.types create mode 100644 tests/baselines/reference/valueAndType_ExportDefault.symbols create mode 100644 tests/baselines/reference/valueAndType_ExportDefault.types create mode 100644 tests/baselines/reference/valueAndType_ExportDestructure.symbols create mode 100644 tests/baselines/reference/valueAndType_ExportDestructure.types create mode 100644 tests/baselines/reference/valueAndType_ExportLet.symbols create mode 100644 tests/baselines/reference/valueAndType_ExportLet.types create mode 100644 tests/baselines/reference/valueAndType_ModuleExports.symbols create mode 100644 tests/baselines/reference/valueAndType_ModuleExports.types create mode 100644 tests/cases/conformance/jsdoc/valueAndType_ExportAs-default.ts create mode 100644 tests/cases/conformance/jsdoc/valueAndType_ExportAs.ts create mode 100644 tests/cases/conformance/jsdoc/valueAndType_ExportDefault-enum.ts create mode 100644 tests/cases/conformance/jsdoc/valueAndType_ExportDefault.ts create mode 100644 tests/cases/conformance/jsdoc/valueAndType_ExportDestructure.ts create mode 100644 tests/cases/conformance/jsdoc/valueAndType_ExportLet.ts create mode 100644 tests/cases/conformance/jsdoc/valueAndType_ModuleExports.ts diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index f61aa3ab900eb..cdd03737553c9 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -567,8 +567,10 @@ namespace ts { // and this case is specially handled. Module augmentations should only be merged with original module definition // and should never be merged directly with other augmentation, and the latter case would be possible if automatic merge is allowed. if (isJSDocTypeAlias(node)) Debug.assert(isInJSFile(node)); // We shouldn't add symbols for JSDoc nodes if not in a JS file. - if ((!isAmbientModule(node) && (hasExportModifier || container.flags & NodeFlags.ExportContext)) || isJSDocTypeAlias(node)) { - if (!container.locals || (hasSyntacticModifier(node, ModifierFlags.Default) && !getDeclarationName(node))) { + const declarationName = getDeclarationName(node); + if ((!isAmbientModule(node) && (hasExportModifier || container.flags & NodeFlags.ExportContext)) + || (isJSDocTypeAlias(node) && !nameIsExported(container, declarationName))) { + if (!container.locals || (hasSyntacticModifier(node, ModifierFlags.Default) && !declarationName)) { return declareSymbol(container.symbol.exports!, container.symbol, node, symbolFlags, symbolExcludes); // No local symbol for an unnamed default! } const exportKind = symbolFlags & SymbolFlags.Value ? SymbolFlags.ExportValue : 0; @@ -583,6 +585,17 @@ namespace ts { } } + function nameIsExported(container: Node, name: __String | undefined): boolean { + if (!name) return false; + return arrayFrom(container.symbol.exports!.values()).some(sym => + sym.declarations.some(decl => { + const expSym = isExportAssignment(decl) ? decl.expression + : isExportSpecifier(decl) ? decl.propertyName + : undefined; + return expSym && isIdentifier(expSym) && expSym.escapedText === name; + })); + } + // All container nodes are kept on a linked list in declaration order. This list is used by // the getLocalNameOfContainer function in the type checker to validate that the local name // used for a container is unique. diff --git a/tests/baselines/reference/valueAndType_ExportAs-default.symbols b/tests/baselines/reference/valueAndType_ExportAs-default.symbols new file mode 100644 index 0000000000000..a5b3eeeefb720 --- /dev/null +++ b/tests/baselines/reference/valueAndType_ExportAs-default.symbols @@ -0,0 +1,19 @@ +=== tests/cases/conformance/jsdoc/def.js === +/** @typedef {number} X */ +const X = { a: 1, m: 1 }; +>X : Symbol(X, Decl(def.js, 1, 5), Decl(def.js, 0, 4)) +>a : Symbol(a, Decl(def.js, 1, 11)) +>m : Symbol(m, Decl(def.js, 1, 17)) + +export { X as default }; +>X : Symbol(X, Decl(def.js, 1, 5), Decl(def.js, 0, 4)) +>default : Symbol(default, Decl(def.js, 2, 8)) + +=== tests/cases/conformance/jsdoc/use.js === +import X from "./def"; +>X : Symbol(X, Decl(use.js, 0, 6)) + +/** @type {X} */ +const n = 1; +>n : Symbol(n, Decl(use.js, 3, 5)) + diff --git a/tests/baselines/reference/valueAndType_ExportAs-default.types b/tests/baselines/reference/valueAndType_ExportAs-default.types new file mode 100644 index 0000000000000..081fd628b6fb5 --- /dev/null +++ b/tests/baselines/reference/valueAndType_ExportAs-default.types @@ -0,0 +1,23 @@ +=== tests/cases/conformance/jsdoc/def.js === +/** @typedef {number} X */ +const X = { a: 1, m: 1 }; +>X : { a: number; m: number; } +>{ a: 1, m: 1 } : { a: number; m: number; } +>a : number +>1 : 1 +>m : number +>1 : 1 + +export { X as default }; +>X : { a: number; m: number; } +>default : { a: number; m: number; } + +=== tests/cases/conformance/jsdoc/use.js === +import X from "./def"; +>X : { a: number; m: number; } + +/** @type {X} */ +const n = 1; +>n : number +>1 : 1 + diff --git a/tests/baselines/reference/valueAndType_ExportAs.symbols b/tests/baselines/reference/valueAndType_ExportAs.symbols new file mode 100644 index 0000000000000..9ba9a980a3852 --- /dev/null +++ b/tests/baselines/reference/valueAndType_ExportAs.symbols @@ -0,0 +1,19 @@ +=== tests/cases/conformance/jsdoc/def.js === +/** @typedef {number} Y */ +const Y = { a: 1, m: 1 }; +>Y : Symbol(Y, Decl(def.js, 1, 5), Decl(def.js, 0, 4)) +>a : Symbol(a, Decl(def.js, 1, 11)) +>m : Symbol(m, Decl(def.js, 1, 17)) + +export { Y as X }; +>Y : Symbol(Y, Decl(def.js, 1, 5), Decl(def.js, 0, 4)) +>X : Symbol(X, Decl(def.js, 2, 8)) + +=== tests/cases/conformance/jsdoc/use.js === +import { X } from "./def"; +>X : Symbol(X, Decl(use.js, 0, 8)) + +/** @type {X} */ +const n = 1; +>n : Symbol(n, Decl(use.js, 3, 5)) + diff --git a/tests/baselines/reference/valueAndType_ExportAs.types b/tests/baselines/reference/valueAndType_ExportAs.types new file mode 100644 index 0000000000000..333321ad9bea9 --- /dev/null +++ b/tests/baselines/reference/valueAndType_ExportAs.types @@ -0,0 +1,23 @@ +=== tests/cases/conformance/jsdoc/def.js === +/** @typedef {number} Y */ +const Y = { a: 1, m: 1 }; +>Y : { a: number; m: number; } +>{ a: 1, m: 1 } : { a: number; m: number; } +>a : number +>1 : 1 +>m : number +>1 : 1 + +export { Y as X }; +>Y : { a: number; m: number; } +>X : { a: number; m: number; } + +=== tests/cases/conformance/jsdoc/use.js === +import { X } from "./def"; +>X : { a: number; m: number; } + +/** @type {X} */ +const n = 1; +>n : number +>1 : 1 + diff --git a/tests/baselines/reference/valueAndType_ExportDefault-enum.symbols b/tests/baselines/reference/valueAndType_ExportDefault-enum.symbols new file mode 100644 index 0000000000000..16948482ecf8b --- /dev/null +++ b/tests/baselines/reference/valueAndType_ExportDefault-enum.symbols @@ -0,0 +1,26 @@ +=== tests/cases/conformance/jsdoc/def.js === +/** @enum {number} */ +const MyEnum = { +>MyEnum : Symbol(MyEnum, Decl(def.js, 1, 5), Decl(def.js, 0, 4)) + + a: 1, +>a : Symbol(a, Decl(def.js, 1, 16)) + + b: 2 +>b : Symbol(b, Decl(def.js, 2, 7)) + +}; +export default MyEnum; +>MyEnum : Symbol(MyEnum, Decl(def.js, 1, 5), Decl(def.js, 0, 4)) + +=== tests/cases/conformance/jsdoc/use.js === +import MyEnum from "./def"; +>MyEnum : Symbol(MyEnum, Decl(use.js, 0, 6)) + +/** @type {MyEnum} */ +const v = MyEnum.b; +>v : Symbol(v, Decl(use.js, 3, 5)) +>MyEnum.b : Symbol(b, Decl(def.js, 2, 7)) +>MyEnum : Symbol(MyEnum, Decl(use.js, 0, 6)) +>b : Symbol(b, Decl(def.js, 2, 7)) + diff --git a/tests/baselines/reference/valueAndType_ExportDefault-enum.types b/tests/baselines/reference/valueAndType_ExportDefault-enum.types new file mode 100644 index 0000000000000..d816067e9f476 --- /dev/null +++ b/tests/baselines/reference/valueAndType_ExportDefault-enum.types @@ -0,0 +1,29 @@ +=== tests/cases/conformance/jsdoc/def.js === +/** @enum {number} */ +const MyEnum = { +>MyEnum : { a: number; b: number; } +>{ a: 1, b: 2} : { a: number; b: number; } + + a: 1, +>a : number +>1 : 1 + + b: 2 +>b : number +>2 : 2 + +}; +export default MyEnum; +>MyEnum : number + +=== tests/cases/conformance/jsdoc/use.js === +import MyEnum from "./def"; +>MyEnum : { a: number; b: number; } + +/** @type {MyEnum} */ +const v = MyEnum.b; +>v : number +>MyEnum.b : number +>MyEnum : { a: number; b: number; } +>b : number + diff --git a/tests/baselines/reference/valueAndType_ExportDefault.symbols b/tests/baselines/reference/valueAndType_ExportDefault.symbols new file mode 100644 index 0000000000000..cbd2fe5b6b746 --- /dev/null +++ b/tests/baselines/reference/valueAndType_ExportDefault.symbols @@ -0,0 +1,18 @@ +=== tests/cases/conformance/jsdoc/def.js === +/** @typedef {number} X */ +const X = { a: 1, m: 1 }; +>X : Symbol(X, Decl(def.js, 1, 5), Decl(def.js, 0, 4)) +>a : Symbol(a, Decl(def.js, 1, 11)) +>m : Symbol(m, Decl(def.js, 1, 17)) + +export default X; +>X : Symbol(X, Decl(def.js, 1, 5), Decl(def.js, 0, 4)) + +=== tests/cases/conformance/jsdoc/use.js === +import X from "./def"; +>X : Symbol(X, Decl(use.js, 0, 6)) + +/** @type {X} */ +const n = 1; +>n : Symbol(n, Decl(use.js, 3, 5)) + diff --git a/tests/baselines/reference/valueAndType_ExportDefault.types b/tests/baselines/reference/valueAndType_ExportDefault.types new file mode 100644 index 0000000000000..9507177b6c3af --- /dev/null +++ b/tests/baselines/reference/valueAndType_ExportDefault.types @@ -0,0 +1,22 @@ +=== tests/cases/conformance/jsdoc/def.js === +/** @typedef {number} X */ +const X = { a: 1, m: 1 }; +>X : { a: number; m: number; } +>{ a: 1, m: 1 } : { a: number; m: number; } +>a : number +>1 : 1 +>m : number +>1 : 1 + +export default X; +>X : number + +=== tests/cases/conformance/jsdoc/use.js === +import X from "./def"; +>X : { a: number; m: number; } + +/** @type {X} */ +const n = 1; +>n : number +>1 : 1 + diff --git a/tests/baselines/reference/valueAndType_ExportDestructure.symbols b/tests/baselines/reference/valueAndType_ExportDestructure.symbols new file mode 100644 index 0000000000000..97200ffb87d11 --- /dev/null +++ b/tests/baselines/reference/valueAndType_ExportDestructure.symbols @@ -0,0 +1,18 @@ +=== tests/cases/conformance/jsdoc/def.js === +/** @typedef {number} X */ +export const { X, Y } = { X: { a: 1, m: 1 }, Y: "why" }; +>X : Symbol(X, Decl(def.js, 1, 14), Decl(def.js, 0, 4)) +>Y : Symbol(Y, Decl(def.js, 1, 17)) +>X : Symbol(X, Decl(def.js, 1, 25)) +>a : Symbol(a, Decl(def.js, 1, 30)) +>m : Symbol(m, Decl(def.js, 1, 36)) +>Y : Symbol(Y, Decl(def.js, 1, 44)) + +=== tests/cases/conformance/jsdoc/use.js === +import { X } from "./def"; +>X : Symbol(X, Decl(use.js, 0, 8)) + +/** @type {X} */ +const n = 1; +>n : Symbol(n, Decl(use.js, 3, 5)) + diff --git a/tests/baselines/reference/valueAndType_ExportDestructure.types b/tests/baselines/reference/valueAndType_ExportDestructure.types new file mode 100644 index 0000000000000..4bf913a996cba --- /dev/null +++ b/tests/baselines/reference/valueAndType_ExportDestructure.types @@ -0,0 +1,24 @@ +=== tests/cases/conformance/jsdoc/def.js === +/** @typedef {number} X */ +export const { X, Y } = { X: { a: 1, m: 1 }, Y: "why" }; +>X : { a: number; m: number; } +>Y : string +>{ X: { a: 1, m: 1 }, Y: "why" } : { X: { a: number; m: number; }; Y: string; } +>X : { a: number; m: number; } +>{ a: 1, m: 1 } : { a: number; m: number; } +>a : number +>1 : 1 +>m : number +>1 : 1 +>Y : string +>"why" : "why" + +=== tests/cases/conformance/jsdoc/use.js === +import { X } from "./def"; +>X : { a: number; m: number; } + +/** @type {X} */ +const n = 1; +>n : number +>1 : 1 + diff --git a/tests/baselines/reference/valueAndType_ExportLet.symbols b/tests/baselines/reference/valueAndType_ExportLet.symbols new file mode 100644 index 0000000000000..173ad65a9b5ca --- /dev/null +++ b/tests/baselines/reference/valueAndType_ExportLet.symbols @@ -0,0 +1,15 @@ +=== tests/cases/conformance/jsdoc/def.js === +/** @typedef {number} X */ +export let X = { a: 1, m: 1 }; +>X : Symbol(X, Decl(def.js, 1, 10), Decl(def.js, 0, 4)) +>a : Symbol(a, Decl(def.js, 1, 16)) +>m : Symbol(m, Decl(def.js, 1, 22)) + +=== tests/cases/conformance/jsdoc/use.js === +import { X } from "./def"; +>X : Symbol(X, Decl(use.js, 0, 8)) + +/** @type {X} */ +const n = 1; +>n : Symbol(n, Decl(use.js, 3, 5)) + diff --git a/tests/baselines/reference/valueAndType_ExportLet.types b/tests/baselines/reference/valueAndType_ExportLet.types new file mode 100644 index 0000000000000..4456e8fe7484b --- /dev/null +++ b/tests/baselines/reference/valueAndType_ExportLet.types @@ -0,0 +1,19 @@ +=== tests/cases/conformance/jsdoc/def.js === +/** @typedef {number} X */ +export let X = { a: 1, m: 1 }; +>X : { a: number; m: number; } +>{ a: 1, m: 1 } : { a: number; m: number; } +>a : number +>1 : 1 +>m : number +>1 : 1 + +=== tests/cases/conformance/jsdoc/use.js === +import { X } from "./def"; +>X : { a: number; m: number; } + +/** @type {X} */ +const n = 1; +>n : number +>1 : 1 + diff --git a/tests/baselines/reference/valueAndType_ModuleExports.symbols b/tests/baselines/reference/valueAndType_ModuleExports.symbols new file mode 100644 index 0000000000000..9dd40252a1c75 --- /dev/null +++ b/tests/baselines/reference/valueAndType_ModuleExports.symbols @@ -0,0 +1,23 @@ +=== tests/cases/conformance/jsdoc/use.js === +const X = require("./def"); +>X : Symbol(X, Decl(use.js, 0, 5)) +>require : Symbol(require) +>"./def" : Symbol("tests/cases/conformance/jsdoc/def", Decl(def.js, 0, 0)) + +/** @type {X} */ +const n = 1; +>n : Symbol(n, Decl(use.js, 3, 5)) + +=== tests/cases/conformance/jsdoc/def.js === +/** @typedef {number} X */ +const X = { a: 1, m: 1 }; +>X : Symbol(X, Decl(def.js, 1, 5), Decl(def.js, 0, 4)) +>a : Symbol(a, Decl(def.js, 1, 11)) +>m : Symbol(m, Decl(def.js, 1, 17)) + +module.exports = X; +>module.exports : Symbol("tests/cases/conformance/jsdoc/def", Decl(def.js, 0, 0)) +>module : Symbol(export=, Decl(def.js, 1, 25)) +>exports : Symbol(export=, Decl(def.js, 1, 25)) +>X : Symbol(X, Decl(def.js, 1, 5), Decl(def.js, 0, 4)) + diff --git a/tests/baselines/reference/valueAndType_ModuleExports.types b/tests/baselines/reference/valueAndType_ModuleExports.types new file mode 100644 index 0000000000000..74d81967be8f5 --- /dev/null +++ b/tests/baselines/reference/valueAndType_ModuleExports.types @@ -0,0 +1,29 @@ +=== tests/cases/conformance/jsdoc/use.js === +const X = require("./def"); +>X : { a: number; m: number; } +>require("./def") : { a: number; m: number; } +>require : any +>"./def" : "./def" + +/** @type {X} */ +const n = 1; +>n : error +>1 : 1 + +=== tests/cases/conformance/jsdoc/def.js === +/** @typedef {number} X */ +const X = { a: 1, m: 1 }; +>X : { a: number; m: number; } +>{ a: 1, m: 1 } : { a: number; m: number; } +>a : number +>1 : 1 +>m : number +>1 : 1 + +module.exports = X; +>module.exports = X : { a: number; m: number; } +>module.exports : { a: number; m: number; } +>module : { "\"tests/cases/conformance/jsdoc/def\"": { a: number; m: number; }; } +>exports : { a: number; m: number; } +>X : { a: number; m: number; } + diff --git a/tests/cases/conformance/jsdoc/valueAndType_ExportAs-default.ts b/tests/cases/conformance/jsdoc/valueAndType_ExportAs-default.ts new file mode 100644 index 0000000000000..dc45b8c9f00c6 --- /dev/null +++ b/tests/cases/conformance/jsdoc/valueAndType_ExportAs-default.ts @@ -0,0 +1,14 @@ +// @noEmit: true +// @allowJs: true +// @checkJs: true + +// @Filename: def.js +/** @typedef {number} X */ +const X = { a: 1, m: 1 }; +export { X as default }; + +// @Filename: use.js +import X from "./def"; + +/** @type {X} */ +const n = 1; diff --git a/tests/cases/conformance/jsdoc/valueAndType_ExportAs.ts b/tests/cases/conformance/jsdoc/valueAndType_ExportAs.ts new file mode 100644 index 0000000000000..0dd5c9eea5964 --- /dev/null +++ b/tests/cases/conformance/jsdoc/valueAndType_ExportAs.ts @@ -0,0 +1,14 @@ +// @noEmit: true +// @allowJs: true +// @checkJs: true + +// @Filename: def.js +/** @typedef {number} Y */ +const Y = { a: 1, m: 1 }; +export { Y as X }; + +// @Filename: use.js +import { X } from "./def"; + +/** @type {X} */ +const n = 1; diff --git a/tests/cases/conformance/jsdoc/valueAndType_ExportDefault-enum.ts b/tests/cases/conformance/jsdoc/valueAndType_ExportDefault-enum.ts new file mode 100644 index 0000000000000..61a7b2614ff9d --- /dev/null +++ b/tests/cases/conformance/jsdoc/valueAndType_ExportDefault-enum.ts @@ -0,0 +1,17 @@ +// @noEmit: true +// @allowJs: true +// @checkJs: true + +// @Filename: def.js +/** @enum {number} */ +const MyEnum = { + a: 1, + b: 2 +}; +export default MyEnum; + +// @Filename: use.js +import MyEnum from "./def"; + +/** @type {MyEnum} */ +const v = MyEnum.b; diff --git a/tests/cases/conformance/jsdoc/valueAndType_ExportDefault.ts b/tests/cases/conformance/jsdoc/valueAndType_ExportDefault.ts new file mode 100644 index 0000000000000..a91dec8bc84cd --- /dev/null +++ b/tests/cases/conformance/jsdoc/valueAndType_ExportDefault.ts @@ -0,0 +1,14 @@ +// @noEmit: true +// @allowJs: true +// @checkJs: true + +// @Filename: def.js +/** @typedef {number} X */ +const X = { a: 1, m: 1 }; +export default X; + +// @Filename: use.js +import X from "./def"; + +/** @type {X} */ +const n = 1; diff --git a/tests/cases/conformance/jsdoc/valueAndType_ExportDestructure.ts b/tests/cases/conformance/jsdoc/valueAndType_ExportDestructure.ts new file mode 100644 index 0000000000000..663a832f4e4dc --- /dev/null +++ b/tests/cases/conformance/jsdoc/valueAndType_ExportDestructure.ts @@ -0,0 +1,13 @@ +// @noEmit: true +// @allowJs: true +// @checkJs: true + +// @Filename: def.js +/** @typedef {number} X */ +export const { X, Y } = { X: { a: 1, m: 1 }, Y: "why" }; + +// @Filename: use.js +import { X } from "./def"; + +/** @type {X} */ +const n = 1; diff --git a/tests/cases/conformance/jsdoc/valueAndType_ExportLet.ts b/tests/cases/conformance/jsdoc/valueAndType_ExportLet.ts new file mode 100644 index 0000000000000..ccfee4fe14616 --- /dev/null +++ b/tests/cases/conformance/jsdoc/valueAndType_ExportLet.ts @@ -0,0 +1,13 @@ +// @noEmit: true +// @allowJs: true +// @checkJs: true + +// @Filename: def.js +/** @typedef {number} X */ +export let X = { a: 1, m: 1 }; + +// @Filename: use.js +import { X } from "./def"; + +/** @type {X} */ +const n = 1; diff --git a/tests/cases/conformance/jsdoc/valueAndType_ModuleExports.ts b/tests/cases/conformance/jsdoc/valueAndType_ModuleExports.ts new file mode 100644 index 0000000000000..3d647c0583f79 --- /dev/null +++ b/tests/cases/conformance/jsdoc/valueAndType_ModuleExports.ts @@ -0,0 +1,14 @@ +// @noEmit: true +// @allowJs: true +// @checkJs: true + +// @Filename: def.js +/** @typedef {number} X */ +const X = { a: 1, m: 1 }; +module.exports = X; + +// @Filename: use.js +const X = require("./def"); + +/** @type {X} */ +const n = 1;