From 0cf100dcf82cbf6bfdab8cb8a343bac81d62846d Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Wed, 29 Jan 2020 09:36:59 -0800 Subject: [PATCH] Add constructor functions to aliasable expressions (#36108) * Add constructor functions to aliasable expressions Fixes #35228, at least the crash. There are still a couple of errors that are probably incorrect. Note that isJSConstructor relies on parent pointers and the ability to merge symbols, so I had to move isAliasSymbolDeclaration (back?) to the checker. * add simple test case * remove errors in test * fix bad merge --- src/compiler/checker.ts | 41 ++++++++++++++- src/compiler/utilities.ts | 29 +---------- ...ationsExportAssignedConstructorFunction.js | 24 +++++++++ ...sExportAssignedConstructorFunction.symbols | 28 ++++++++++ ...onsExportAssignedConstructorFunction.types | 35 +++++++++++++ ...ignedConstructorFunctionWithSub.errors.txt | 23 ++++++++ ...xportAssignedConstructorFunctionWithSub.js | 24 +++++++++ ...AssignedConstructorFunctionWithSub.symbols | 38 ++++++++++++++ ...rtAssignedConstructorFunctionWithSub.types | 52 +++++++++++++++++++ ...ationsExportAssignedConstructorFunction.ts | 14 +++++ ...xportAssignedConstructorFunctionWithSub.ts | 16 ++++++ 11 files changed, 294 insertions(+), 30 deletions(-) create mode 100644 tests/baselines/reference/jsDeclarationsExportAssignedConstructorFunction.js create mode 100644 tests/baselines/reference/jsDeclarationsExportAssignedConstructorFunction.symbols create mode 100644 tests/baselines/reference/jsDeclarationsExportAssignedConstructorFunction.types create mode 100644 tests/baselines/reference/jsDeclarationsExportAssignedConstructorFunctionWithSub.errors.txt create mode 100644 tests/baselines/reference/jsDeclarationsExportAssignedConstructorFunctionWithSub.js create mode 100644 tests/baselines/reference/jsDeclarationsExportAssignedConstructorFunctionWithSub.symbols create mode 100644 tests/baselines/reference/jsDeclarationsExportAssignedConstructorFunctionWithSub.types create mode 100644 tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunction.ts create mode 100644 tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunctionWithSub.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d9438f32a95..2217f2f430b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2181,6 +2181,43 @@ namespace ts { return find(symbol.declarations, isAliasSymbolDeclaration); } + /** + * An alias symbol is created by one of the following declarations: + * import = ... + * import from ... + * import * as from ... + * import { x as } from ... + * export { x as } from ... + * export * as ns from ... + * export = + * export default + * module.exports = + * {} + * {name: } + */ + function isAliasSymbolDeclaration(node: Node): boolean { + return node.kind === SyntaxKind.ImportEqualsDeclaration || + node.kind === SyntaxKind.NamespaceExportDeclaration || + node.kind === SyntaxKind.ImportClause && !!(node).name || + node.kind === SyntaxKind.NamespaceImport || + node.kind === SyntaxKind.NamespaceExport || + node.kind === SyntaxKind.ImportSpecifier || + node.kind === SyntaxKind.ExportSpecifier || + node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(node) || + isBinaryExpression(node) && getAssignmentDeclarationKind(node) === AssignmentDeclarationKind.ModuleExports && exportAssignmentIsAlias(node) || + isPropertyAccessExpression(node) + && isBinaryExpression(node.parent) + && node.parent.left === node + && node.parent.operatorToken.kind === SyntaxKind.EqualsToken + && isAliasableOrJsExpression(node.parent.right) || + node.kind === SyntaxKind.ShorthandPropertyAssignment || + node.kind === SyntaxKind.PropertyAssignment && isAliasableOrJsExpression((node as PropertyAssignment).initializer); + } + + function isAliasableOrJsExpression(e: Expression) { + return isAliasableExpression(e) || isFunctionExpression(e) && isJSConstructor(e); + } + function getTargetOfImportEqualsDeclaration(node: ImportEqualsDeclaration, dontResolveAlias: boolean): Symbol | undefined { if (node.moduleReference.kind === SyntaxKind.ExternalModuleReference) { return resolveExternalModuleSymbol(resolveExternalModuleName(node, getExternalModuleImportEqualsDeclarationExpression(node))); @@ -5784,8 +5821,8 @@ namespace ts { function serializeAsAlias(symbol: Symbol, localName: string, modifierFlags: ModifierFlags) { // synthesize an alias, eg `export { symbolName as Name }` - // need to mark the alias `symbol` points - // at as something we need to serialize as a private declaration as well + // need to mark the alias `symbol` points at + // as something we need to serialize as a private declaration as well const node = getDeclarationOfAliasSymbol(symbol); if (!node) return Debug.fail(); const target = getMergedSymbol(getTargetOfAliasDeclaration(node, /*dontRecursivelyResolve*/ true)); diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 167ee1aef2a..e8883714a53 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2738,33 +2738,6 @@ namespace ts { return false; } - // An alias symbol is created by one of the following declarations: - // import = ... - // import from ... - // import * as from ... - // import { x as } from ... - // export { x as } from ... - // export * as ns from ... - // export = - // export default - // module.exports = - // {} - // {name: } - export function isAliasSymbolDeclaration(node: Node): boolean { - return node.kind === SyntaxKind.ImportEqualsDeclaration || - node.kind === SyntaxKind.NamespaceExportDeclaration || - node.kind === SyntaxKind.ImportClause && !!(node).name || - node.kind === SyntaxKind.NamespaceImport || - node.kind === SyntaxKind.NamespaceExport || - node.kind === SyntaxKind.ImportSpecifier || - node.kind === SyntaxKind.ExportSpecifier || - node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(node) || - isBinaryExpression(node) && getAssignmentDeclarationKind(node) === AssignmentDeclarationKind.ModuleExports && exportAssignmentIsAlias(node) || - isPropertyAccessExpression(node) && isBinaryExpression(node.parent) && node.parent.left === node && node.parent.operatorToken.kind === SyntaxKind.EqualsToken && isAliasableExpression(node.parent.right) || - node.kind === SyntaxKind.ShorthandPropertyAssignment || - node.kind === SyntaxKind.PropertyAssignment && isAliasableExpression((node as PropertyAssignment).initializer); - } - export function getTypeOnlyCompatibleAliasDeclarationFromName(node: Identifier): TypeOnlyCompatibleAliasDeclaration | undefined { switch (node.parent.kind) { case SyntaxKind.ImportClause: @@ -2775,7 +2748,7 @@ namespace ts { } } - function isAliasableExpression(e: Expression) { + export function isAliasableExpression(e: Expression) { return isEntityNameExpression(e) || isClassExpression(e); } diff --git a/tests/baselines/reference/jsDeclarationsExportAssignedConstructorFunction.js b/tests/baselines/reference/jsDeclarationsExportAssignedConstructorFunction.js new file mode 100644 index 00000000000..aa2f0d2a0a9 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsExportAssignedConstructorFunction.js @@ -0,0 +1,24 @@ +//// [jsDeclarationsExportAssignedConstructorFunction.js] +/** @constructor */ +module.exports.MyClass = function() { + this.x = 1 +} +module.exports.MyClass.prototype = { + a: function() { + } +} + + +//// [jsDeclarationsExportAssignedConstructorFunction.js] +/** @constructor */ +module.exports.MyClass = function () { + this.x = 1; +}; +module.exports.MyClass.prototype = { + a: function () { + } +}; + + +//// [jsDeclarationsExportAssignedConstructorFunction.d.ts] +export {}; diff --git a/tests/baselines/reference/jsDeclarationsExportAssignedConstructorFunction.symbols b/tests/baselines/reference/jsDeclarationsExportAssignedConstructorFunction.symbols new file mode 100644 index 00000000000..77c74ae16ec --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsExportAssignedConstructorFunction.symbols @@ -0,0 +1,28 @@ +=== tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunction.js === +/** @constructor */ +module.exports.MyClass = function() { +>module.exports.MyClass : Symbol(MyClass, Decl(jsDeclarationsExportAssignedConstructorFunction.js, 0, 0), Decl(jsDeclarationsExportAssignedConstructorFunction.js, 4, 15)) +>module.exports : Symbol(MyClass, Decl(jsDeclarationsExportAssignedConstructorFunction.js, 0, 0), Decl(jsDeclarationsExportAssignedConstructorFunction.js, 4, 15)) +>module : Symbol(module, Decl(jsDeclarationsExportAssignedConstructorFunction.js, 0, 0)) +>exports : Symbol("tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunction", Decl(jsDeclarationsExportAssignedConstructorFunction.js, 0, 0)) +>MyClass : Symbol(MyClass, Decl(jsDeclarationsExportAssignedConstructorFunction.js, 0, 0), Decl(jsDeclarationsExportAssignedConstructorFunction.js, 4, 15)) + + this.x = 1 +>this.x : Symbol(MyClass.x, Decl(jsDeclarationsExportAssignedConstructorFunction.js, 1, 37)) +>this : Symbol(MyClass, Decl(jsDeclarationsExportAssignedConstructorFunction.js, 1, 24)) +>x : Symbol(MyClass.x, Decl(jsDeclarationsExportAssignedConstructorFunction.js, 1, 37)) +} +module.exports.MyClass.prototype = { +>module.exports.MyClass.prototype : Symbol(MyClass.prototype, Decl(jsDeclarationsExportAssignedConstructorFunction.js, 3, 1)) +>module.exports.MyClass : Symbol(MyClass, Decl(jsDeclarationsExportAssignedConstructorFunction.js, 0, 0), Decl(jsDeclarationsExportAssignedConstructorFunction.js, 4, 15)) +>module.exports : Symbol("tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunction", Decl(jsDeclarationsExportAssignedConstructorFunction.js, 0, 0)) +>module : Symbol(module, Decl(jsDeclarationsExportAssignedConstructorFunction.js, 0, 0)) +>exports : Symbol("tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunction", Decl(jsDeclarationsExportAssignedConstructorFunction.js, 0, 0)) +>MyClass : Symbol(MyClass, Decl(jsDeclarationsExportAssignedConstructorFunction.js, 0, 0), Decl(jsDeclarationsExportAssignedConstructorFunction.js, 4, 15)) +>prototype : Symbol(MyClass.prototype, Decl(jsDeclarationsExportAssignedConstructorFunction.js, 3, 1)) + + a: function() { +>a : Symbol(a, Decl(jsDeclarationsExportAssignedConstructorFunction.js, 4, 36)) + } +} + diff --git a/tests/baselines/reference/jsDeclarationsExportAssignedConstructorFunction.types b/tests/baselines/reference/jsDeclarationsExportAssignedConstructorFunction.types new file mode 100644 index 00000000000..bbdaa717fb2 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsExportAssignedConstructorFunction.types @@ -0,0 +1,35 @@ +=== tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunction.js === +/** @constructor */ +module.exports.MyClass = function() { +>module.exports.MyClass = function() { this.x = 1} : typeof MyClass +>module.exports.MyClass : typeof MyClass +>module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunction") +>module : { "\"tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunction\"": typeof import("tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunction"); } +>exports : typeof import("tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunction") +>MyClass : typeof MyClass +>function() { this.x = 1} : typeof MyClass + + this.x = 1 +>this.x = 1 : 1 +>this.x : number +>this : this +>x : number +>1 : 1 +} +module.exports.MyClass.prototype = { +>module.exports.MyClass.prototype = { a: function() { }} : { a: () => void; } +>module.exports.MyClass.prototype : { a: () => void; } +>module.exports.MyClass : typeof MyClass +>module.exports : typeof import("tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunction") +>module : { "\"tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunction\"": typeof import("tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunction"); } +>exports : typeof import("tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunction") +>MyClass : typeof MyClass +>prototype : { a: () => void; } +>{ a: function() { }} : { a: () => void; } + + a: function() { +>a : () => void +>function() { } : () => void + } +} + diff --git a/tests/baselines/reference/jsDeclarationsExportAssignedConstructorFunctionWithSub.errors.txt b/tests/baselines/reference/jsDeclarationsExportAssignedConstructorFunctionWithSub.errors.txt new file mode 100644 index 00000000000..b0aca99dcab --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsExportAssignedConstructorFunctionWithSub.errors.txt @@ -0,0 +1,23 @@ +tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunctionWithSub.js(4,1): error TS9005: Declaration emit for this file requires using private name 'exports'. An explicit type annotation may unblock declaration emit. +tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunctionWithSub.js(5,10): error TS2339: Property 't' does not exist on type '{ "\"tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunctionWithSub\"": typeof exports; }'. +tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunctionWithSub.js(8,10): error TS2339: Property 'instance' does not exist on type 'typeof exports'. + + +==== tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunctionWithSub.js (3 errors) ==== + /** + * @param {number} p + */ + module.exports = function (p) { + ~~~~~~ +!!! error TS9005: Declaration emit for this file requires using private name 'exports'. An explicit type annotation may unblock declaration emit. + this.t = 12 + p; + ~ +!!! error TS2339: Property 't' does not exist on type '{ "\"tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunctionWithSub\"": typeof exports; }'. + } + module.exports.Sub = function() { + this.instance = new module.exports(10); + ~~~~~~~~ +!!! error TS2339: Property 'instance' does not exist on type 'typeof exports'. + } + module.exports.Sub.prototype = { } + \ No newline at end of file diff --git a/tests/baselines/reference/jsDeclarationsExportAssignedConstructorFunctionWithSub.js b/tests/baselines/reference/jsDeclarationsExportAssignedConstructorFunctionWithSub.js new file mode 100644 index 00000000000..42570cfff79 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsExportAssignedConstructorFunctionWithSub.js @@ -0,0 +1,24 @@ +//// [jsDeclarationsExportAssignedConstructorFunctionWithSub.js] +/** + * @param {number} p + */ +module.exports = function (p) { + this.t = 12 + p; +} +module.exports.Sub = function() { + this.instance = new module.exports(10); +} +module.exports.Sub.prototype = { } + + +//// [jsDeclarationsExportAssignedConstructorFunctionWithSub.js] +/** + * @param {number} p + */ +module.exports = function (p) { + this.t = 12 + p; +}; +module.exports.Sub = function () { + this.instance = new module.exports(10); +}; +module.exports.Sub.prototype = {}; diff --git a/tests/baselines/reference/jsDeclarationsExportAssignedConstructorFunctionWithSub.symbols b/tests/baselines/reference/jsDeclarationsExportAssignedConstructorFunctionWithSub.symbols new file mode 100644 index 00000000000..9f570d90194 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsExportAssignedConstructorFunctionWithSub.symbols @@ -0,0 +1,38 @@ +=== tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunctionWithSub.js === +/** + * @param {number} p + */ +module.exports = function (p) { +>module.exports : Symbol("tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunctionWithSub", Decl(jsDeclarationsExportAssignedConstructorFunctionWithSub.js, 0, 0)) +>module : Symbol(export=, Decl(jsDeclarationsExportAssignedConstructorFunctionWithSub.js, 0, 0)) +>exports : Symbol(export=, Decl(jsDeclarationsExportAssignedConstructorFunctionWithSub.js, 0, 0)) +>p : Symbol(p, Decl(jsDeclarationsExportAssignedConstructorFunctionWithSub.js, 3, 27)) + + this.t = 12 + p; +>this : Symbol(module, Decl(jsDeclarationsExportAssignedConstructorFunctionWithSub.js, 0, 0), Decl(jsDeclarationsExportAssignedConstructorFunctionWithSub.js, 7, 23)) +>t : Symbol(exports.t, Decl(jsDeclarationsExportAssignedConstructorFunctionWithSub.js, 3, 31)) +>p : Symbol(p, Decl(jsDeclarationsExportAssignedConstructorFunctionWithSub.js, 3, 27)) +} +module.exports.Sub = function() { +>module.exports.Sub : Symbol(Sub, Decl(jsDeclarationsExportAssignedConstructorFunctionWithSub.js, 5, 1), Decl(jsDeclarationsExportAssignedConstructorFunctionWithSub.js, 9, 15)) +>module.exports : Symbol(Sub, Decl(jsDeclarationsExportAssignedConstructorFunctionWithSub.js, 5, 1), Decl(jsDeclarationsExportAssignedConstructorFunctionWithSub.js, 9, 15)) +>module : Symbol(module, Decl(jsDeclarationsExportAssignedConstructorFunctionWithSub.js, 0, 0), Decl(jsDeclarationsExportAssignedConstructorFunctionWithSub.js, 7, 23)) +>exports : Symbol("tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunctionWithSub", Decl(jsDeclarationsExportAssignedConstructorFunctionWithSub.js, 0, 0)) +>Sub : Symbol(Sub, Decl(jsDeclarationsExportAssignedConstructorFunctionWithSub.js, 5, 1), Decl(jsDeclarationsExportAssignedConstructorFunctionWithSub.js, 9, 15)) + + this.instance = new module.exports(10); +>this : Symbol(exports, Decl(jsDeclarationsExportAssignedConstructorFunctionWithSub.js, 3, 16)) +>instance : Symbol(Sub.instance, Decl(jsDeclarationsExportAssignedConstructorFunctionWithSub.js, 6, 33)) +>module.exports : Symbol("tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunctionWithSub", Decl(jsDeclarationsExportAssignedConstructorFunctionWithSub.js, 0, 0)) +>module : Symbol(module, Decl(jsDeclarationsExportAssignedConstructorFunctionWithSub.js, 0, 0), Decl(jsDeclarationsExportAssignedConstructorFunctionWithSub.js, 7, 23)) +>exports : Symbol("tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunctionWithSub", Decl(jsDeclarationsExportAssignedConstructorFunctionWithSub.js, 0, 0)) +} +module.exports.Sub.prototype = { } +>module.exports.Sub.prototype : Symbol(Sub.prototype, Decl(jsDeclarationsExportAssignedConstructorFunctionWithSub.js, 8, 1)) +>module.exports.Sub : Symbol(Sub, Decl(jsDeclarationsExportAssignedConstructorFunctionWithSub.js, 5, 1), Decl(jsDeclarationsExportAssignedConstructorFunctionWithSub.js, 9, 15)) +>module.exports : Symbol("tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunctionWithSub", Decl(jsDeclarationsExportAssignedConstructorFunctionWithSub.js, 0, 0)) +>module : Symbol(module, Decl(jsDeclarationsExportAssignedConstructorFunctionWithSub.js, 0, 0), Decl(jsDeclarationsExportAssignedConstructorFunctionWithSub.js, 7, 23)) +>exports : Symbol("tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunctionWithSub", Decl(jsDeclarationsExportAssignedConstructorFunctionWithSub.js, 0, 0)) +>Sub : Symbol(Sub, Decl(jsDeclarationsExportAssignedConstructorFunctionWithSub.js, 5, 1), Decl(jsDeclarationsExportAssignedConstructorFunctionWithSub.js, 9, 15)) +>prototype : Symbol(Sub.prototype, Decl(jsDeclarationsExportAssignedConstructorFunctionWithSub.js, 8, 1)) + diff --git a/tests/baselines/reference/jsDeclarationsExportAssignedConstructorFunctionWithSub.types b/tests/baselines/reference/jsDeclarationsExportAssignedConstructorFunctionWithSub.types new file mode 100644 index 00000000000..d40012a7ccb --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsExportAssignedConstructorFunctionWithSub.types @@ -0,0 +1,52 @@ +=== tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunctionWithSub.js === +/** + * @param {number} p + */ +module.exports = function (p) { +>module.exports = function (p) { this.t = 12 + p;} : typeof exports +>module.exports : typeof exports +>module : { "\"tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunctionWithSub\"": typeof exports; } +>exports : typeof exports +>function (p) { this.t = 12 + p;} : typeof exports +>p : number + + this.t = 12 + p; +>this.t = 12 + p : number +>this.t : any +>this : { "\"tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunctionWithSub\"": typeof exports; } +>t : any +>12 + p : number +>12 : 12 +>p : number +} +module.exports.Sub = function() { +>module.exports.Sub = function() { this.instance = new module.exports(10);} : typeof Sub +>module.exports.Sub : typeof Sub +>module.exports : typeof exports +>module : { "\"tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunctionWithSub\"": typeof exports; } +>exports : typeof exports +>Sub : typeof Sub +>function() { this.instance = new module.exports(10);} : typeof Sub + + this.instance = new module.exports(10); +>this.instance = new module.exports(10) : exports +>this.instance : any +>this : typeof exports +>instance : any +>new module.exports(10) : exports +>module.exports : typeof exports +>module : { "\"tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunctionWithSub\"": typeof exports; } +>exports : typeof exports +>10 : 10 +} +module.exports.Sub.prototype = { } +>module.exports.Sub.prototype = { } : {} +>module.exports.Sub.prototype : {} +>module.exports.Sub : typeof Sub +>module.exports : typeof exports +>module : { "\"tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunctionWithSub\"": typeof exports; } +>exports : typeof exports +>Sub : typeof Sub +>prototype : {} +>{ } : {} + diff --git a/tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunction.ts b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunction.ts new file mode 100644 index 00000000000..66beb67e019 --- /dev/null +++ b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunction.ts @@ -0,0 +1,14 @@ +// @allowJs: true +// @checkJs: true +// @target: es5 +// @outDir: ./out +// @declaration: true +// @filename: jsDeclarationsExportAssignedConstructorFunction.js +/** @constructor */ +module.exports.MyClass = function() { + this.x = 1 +} +module.exports.MyClass.prototype = { + a: function() { + } +} diff --git a/tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunctionWithSub.ts b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunctionWithSub.ts new file mode 100644 index 00000000000..ff33f0dd466 --- /dev/null +++ b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunctionWithSub.ts @@ -0,0 +1,16 @@ +// @allowJs: true +// @checkJs: true +// @target: es5 +// @outDir: ./out +// @declaration: true +// @filename: jsDeclarationsExportAssignedConstructorFunctionWithSub.js +/** + * @param {number} p + */ +module.exports = function (p) { + this.t = 12 + p; +} +module.exports.Sub = function() { + this.instance = new module.exports(10); +} +module.exports.Sub.prototype = { }