diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0a9740a73e414..0b255a6b00249 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4208,6 +4208,10 @@ namespace ts { return flags & TypeFormatFlags.NodeBuilderFlagsMask; } + function isClassInstanceSide(type: Type) { + return !!type.symbol && !!(type.symbol.flags & SymbolFlags.Class) && (type === getDeclaredTypeOfClassOrInterface(type.symbol) || !!(getObjectFlags(type) & ObjectFlags.IsClassInstanceClone)); + } + function createNodeBuilder() { return { typeToTypeNode: (type: Type, enclosingDeclaration?: Node, flags?: NodeBuilderFlags, tracker?: SymbolTracker) => @@ -4505,16 +4509,16 @@ namespace ts { const typeId = type.id; const symbol = type.symbol; if (symbol) { + const isInstanceType = isClassInstanceSide(type) ? SymbolFlags.Type : SymbolFlags.Value; if (isJSConstructor(symbol.valueDeclaration)) { // Instance and static types share the same symbol; only add 'typeof' for the static side. - const isInstanceType = type === getDeclaredTypeOfClassOrInterface(symbol) ? SymbolFlags.Type : SymbolFlags.Value; return symbolToTypeNode(symbol, context, isInstanceType); } // Always use 'typeof T' for type of class, enum, and module objects else if (symbol.flags & SymbolFlags.Class && !getBaseTypeVariableOfClass(symbol) && !(symbol.valueDeclaration.kind === SyntaxKind.ClassExpression && context.flags & NodeBuilderFlags.WriteClassExpressionAsTypeLiteral) || symbol.flags & (SymbolFlags.Enum | SymbolFlags.ValueModule) || shouldWriteTypeOfFunctionSymbol()) { - return symbolToTypeNode(symbol, context, SymbolFlags.Value); + return symbolToTypeNode(symbol, context, isInstanceType); } else if (context.visitedTypes?.has(typeId)) { // If type is an anonymous type literal in a type alias declaration, use type alias name @@ -6541,7 +6545,7 @@ namespace ts { function isNamespaceMember(p: Symbol) { return !!(p.flags & (SymbolFlags.Type | SymbolFlags.Namespace | SymbolFlags.Alias)) || - !(p.flags & SymbolFlags.Prototype || p.escapedName === "prototype" || p.valueDeclaration && isClassLike(p.valueDeclaration.parent)); + !(p.flags & SymbolFlags.Prototype || p.escapedName === "prototype" || p.valueDeclaration && getEffectiveModifierFlags(p.valueDeclaration) & ModifierFlags.Static && isClassLike(p.valueDeclaration.parent)); } function serializeAsClass(symbol: Symbol, localName: string, modifierFlags: ModifierFlags) { @@ -6843,7 +6847,8 @@ namespace ts { return getObjectFlags(typeToSerialize) & (ObjectFlags.Anonymous | ObjectFlags.Mapped) && !getIndexInfoOfType(typeToSerialize, IndexKind.String) && !getIndexInfoOfType(typeToSerialize, IndexKind.Number) && - !!(length(getPropertiesOfType(typeToSerialize)) || length(getSignaturesOfType(typeToSerialize, SignatureKind.Call))) && + !isClassInstanceSide(typeToSerialize) && // While a class instance is potentially representable as a NS, prefer printing a reference to the instance type and serializing the class + !!(length(filter(getPropertiesOfType(typeToSerialize), isNamespaceMember)) || length(getSignaturesOfType(typeToSerialize, SignatureKind.Call))) && !length(getSignaturesOfType(typeToSerialize, SignatureKind.Construct)) && // TODO: could probably serialize as function + ns + class, now that that's OK !getDeclarationWithTypeAnnotation(hostSymbol, enclosingDeclaration) && !(typeToSerialize.symbol && some(typeToSerialize.symbol.declarations, d => getSourceFileOfNode(d) !== ctxSrc)) && @@ -8096,6 +8101,7 @@ namespace ts { const exportedType = resolveStructuredTypeMembers(type as ObjectType); const members = createSymbolTable(); copyEntries(exportedType.members, members); + const initialSize = members.size; if (resolvedSymbol && !resolvedSymbol.exports) { resolvedSymbol.exports = createSymbolTable(); } @@ -8138,13 +8144,16 @@ namespace ts { } }); const result = createAnonymousType( - exportedType.symbol, + initialSize !== members.size ? undefined : exportedType.symbol, // Only set the type's symbol if it looks to be the same as the original type members, exportedType.callSignatures, exportedType.constructSignatures, exportedType.stringIndexInfo, exportedType.numberIndexInfo); result.objectFlags |= (getObjectFlags(type) & ObjectFlags.JSLiteral); // Propagate JSLiteral flag + if (result.symbol && result.symbol.flags & SymbolFlags.Class && type === getDeclaredTypeOfClassOrInterface(result.symbol)) { + result.objectFlags |= ObjectFlags.IsClassInstanceClone; // Propagate the knowledge that this type is equivalent to the symbol's class instance type + } return result; } if (isEmptyArrayLiteralType(type)) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 69d3e9b3d94d9..7f37af1cdeaf7 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5016,6 +5016,8 @@ namespace ts { IsNeverIntersectionComputed = 1 << 28, // IsNeverLike flag has been computed /* @internal */ IsNeverIntersection = 1 << 29, // Intersection reduces to never + /* @internal */ + IsClassInstanceClone = 1 << 30, // Type is a clone of a class instance type ClassOrInterface = Class | Interface, /* @internal */ RequiresWidening = ContainsWideningType | ContainsObjectOrArrayLiteral, diff --git a/tests/baselines/reference/jsDeclarationsExportAssignedClassInstance1.js b/tests/baselines/reference/jsDeclarationsExportAssignedClassInstance1.js new file mode 100644 index 0000000000000..18f45083a770a --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsExportAssignedClassInstance1.js @@ -0,0 +1,19 @@ +//// [index.js] +class Foo {} + +module.exports = new Foo(); + +//// [index.js] +var Foo = /** @class */ (function () { + function Foo() { + } + return Foo; +}()); +module.exports = new Foo(); + + +//// [index.d.ts] +declare const _exports: Foo; +export = _exports; +declare class Foo { +} diff --git a/tests/baselines/reference/jsDeclarationsExportAssignedClassInstance1.symbols b/tests/baselines/reference/jsDeclarationsExportAssignedClassInstance1.symbols new file mode 100644 index 0000000000000..b2812517acfd0 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsExportAssignedClassInstance1.symbols @@ -0,0 +1,10 @@ +=== tests/cases/conformance/jsdoc/declarations/index.js === +class Foo {} +>Foo : Symbol(Foo, Decl(index.js, 0, 0)) + +module.exports = new Foo(); +>module.exports : Symbol("tests/cases/conformance/jsdoc/declarations/index", Decl(index.js, 0, 0)) +>module : Symbol(export=, Decl(index.js, 0, 12)) +>exports : Symbol(export=, Decl(index.js, 0, 12)) +>Foo : Symbol(Foo, Decl(index.js, 0, 0)) + diff --git a/tests/baselines/reference/jsDeclarationsExportAssignedClassInstance1.types b/tests/baselines/reference/jsDeclarationsExportAssignedClassInstance1.types new file mode 100644 index 0000000000000..868d6e684c6d5 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsExportAssignedClassInstance1.types @@ -0,0 +1,12 @@ +=== tests/cases/conformance/jsdoc/declarations/index.js === +class Foo {} +>Foo : Foo + +module.exports = new Foo(); +>module.exports = new Foo() : Foo +>module.exports : Foo +>module : { "\"tests/cases/conformance/jsdoc/declarations/index\"": Foo; } +>exports : Foo +>new Foo() : Foo +>Foo : typeof Foo + diff --git a/tests/baselines/reference/jsDeclarationsExportAssignedClassInstance2.js b/tests/baselines/reference/jsDeclarationsExportAssignedClassInstance2.js new file mode 100644 index 0000000000000..2b03f73a4f9d0 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsExportAssignedClassInstance2.js @@ -0,0 +1,26 @@ +//// [index.js] +class Foo { + static stat = 10; + member = 10; +} + +module.exports = new Foo(); + +//// [index.js] +var Foo = /** @class */ (function () { + function Foo() { + this.member = 10; + } + Foo.stat = 10; + return Foo; +}()); +module.exports = new Foo(); + + +//// [index.d.ts] +declare const _exports: Foo; +export = _exports; +declare class Foo { + static stat: number; + member: number; +} diff --git a/tests/baselines/reference/jsDeclarationsExportAssignedClassInstance2.symbols b/tests/baselines/reference/jsDeclarationsExportAssignedClassInstance2.symbols new file mode 100644 index 0000000000000..bf9e5186a9bae --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsExportAssignedClassInstance2.symbols @@ -0,0 +1,17 @@ +=== tests/cases/conformance/jsdoc/declarations/index.js === +class Foo { +>Foo : Symbol(Foo, Decl(index.js, 0, 0)) + + static stat = 10; +>stat : Symbol(Foo.stat, Decl(index.js, 0, 11)) + + member = 10; +>member : Symbol(Foo.member, Decl(index.js, 1, 21)) +} + +module.exports = new Foo(); +>module.exports : Symbol("tests/cases/conformance/jsdoc/declarations/index", Decl(index.js, 0, 0)) +>module : Symbol(export=, Decl(index.js, 3, 1)) +>exports : Symbol(export=, Decl(index.js, 3, 1)) +>Foo : Symbol(Foo, Decl(index.js, 0, 0)) + diff --git a/tests/baselines/reference/jsDeclarationsExportAssignedClassInstance2.types b/tests/baselines/reference/jsDeclarationsExportAssignedClassInstance2.types new file mode 100644 index 0000000000000..dda0c2e18a9b8 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsExportAssignedClassInstance2.types @@ -0,0 +1,21 @@ +=== tests/cases/conformance/jsdoc/declarations/index.js === +class Foo { +>Foo : Foo + + static stat = 10; +>stat : number +>10 : 10 + + member = 10; +>member : number +>10 : 10 +} + +module.exports = new Foo(); +>module.exports = new Foo() : Foo +>module.exports : Foo +>module : { "\"tests/cases/conformance/jsdoc/declarations/index\"": Foo; } +>exports : Foo +>new Foo() : Foo +>Foo : typeof Foo + diff --git a/tests/baselines/reference/jsDeclarationsExportAssignedClassInstance3.js b/tests/baselines/reference/jsDeclarationsExportAssignedClassInstance3.js new file mode 100644 index 0000000000000..3d8a67223a83f --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsExportAssignedClassInstance3.js @@ -0,0 +1,25 @@ +//// [index.js] +class Foo { + static stat = 10; + member = 10; +} + +module.exports = new Foo(); + +module.exports.additional = 20; + +//// [index.js] +var Foo = /** @class */ (function () { + function Foo() { + this.member = 10; + } + Foo.stat = 10; + return Foo; +}()); +module.exports = new Foo(); +module.exports.additional = 20; + + +//// [index.d.ts] +export const member: number; +export const additional: number; diff --git a/tests/baselines/reference/jsDeclarationsExportAssignedClassInstance3.symbols b/tests/baselines/reference/jsDeclarationsExportAssignedClassInstance3.symbols new file mode 100644 index 0000000000000..1da8f49afe8d0 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsExportAssignedClassInstance3.symbols @@ -0,0 +1,24 @@ +=== tests/cases/conformance/jsdoc/declarations/index.js === +class Foo { +>Foo : Symbol(Foo, Decl(index.js, 0, 0)) + + static stat = 10; +>stat : Symbol(Foo.stat, Decl(index.js, 0, 11)) + + member = 10; +>member : Symbol(Foo.member, Decl(index.js, 1, 21)) +} + +module.exports = new Foo(); +>module.exports : Symbol("tests/cases/conformance/jsdoc/declarations/index", Decl(index.js, 0, 0)) +>module : Symbol(export=, Decl(index.js, 3, 1)) +>exports : Symbol(export=, Decl(index.js, 3, 1)) +>Foo : Symbol(Foo, Decl(index.js, 0, 0)) + +module.exports.additional = 20; +>module.exports.additional : Symbol(additional, Decl(index.js, 5, 27)) +>module.exports : Symbol(additional, Decl(index.js, 5, 27)) +>module : Symbol(module, Decl(index.js, 3, 1)) +>exports : Symbol("tests/cases/conformance/jsdoc/declarations/index", Decl(index.js, 0, 0)) +>additional : Symbol(additional, Decl(index.js, 5, 27)) + diff --git a/tests/baselines/reference/jsDeclarationsExportAssignedClassInstance3.types b/tests/baselines/reference/jsDeclarationsExportAssignedClassInstance3.types new file mode 100644 index 0000000000000..ee1de06b04e53 --- /dev/null +++ b/tests/baselines/reference/jsDeclarationsExportAssignedClassInstance3.types @@ -0,0 +1,30 @@ +=== tests/cases/conformance/jsdoc/declarations/index.js === +class Foo { +>Foo : Foo + + static stat = 10; +>stat : number +>10 : 10 + + member = 10; +>member : number +>10 : 10 +} + +module.exports = new Foo(); +>module.exports = new Foo() : { member: number; additional: number; } +>module.exports : { member: number; additional: number; } +>module : { "\"tests/cases/conformance/jsdoc/declarations/index\"": { member: number; additional: number; }; } +>exports : { member: number; additional: number; } +>new Foo() : Foo +>Foo : typeof Foo + +module.exports.additional = 20; +>module.exports.additional = 20 : 20 +>module.exports.additional : number +>module.exports : { member: number; additional: number; } +>module : { "\"tests/cases/conformance/jsdoc/declarations/index\"": { member: number; additional: number; }; } +>exports : { member: number; additional: number; } +>additional : number +>20 : 20 + diff --git a/tests/baselines/reference/jsDeclarationsExportAssignedConstructorFunctionWithSub.errors.txt b/tests/baselines/reference/jsDeclarationsExportAssignedConstructorFunctionWithSub.errors.txt index 44efa54d013cb..c97f0000cb8a2 100644 --- a/tests/baselines/reference/jsDeclarationsExportAssignedConstructorFunctionWithSub.errors.txt +++ b/tests/baselines/reference/jsDeclarationsExportAssignedConstructorFunctionWithSub.errors.txt @@ -1,12 +1,15 @@ +tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunctionWithSub.js(4,1): error TS9005: Declaration emit for this file requires using private name 'Sub'. An explicit type annotation may unblock declaration emit. 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 (1 errors) ==== +==== tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunctionWithSub.js (2 errors) ==== /** * @param {number} p */ module.exports = function (p) { ~~~~~~ +!!! error TS9005: Declaration emit for this file requires using private name 'Sub'. An explicit type annotation may unblock declaration emit. + ~~~~~~ !!! error TS9005: Declaration emit for this file requires using private name 'exports'. An explicit type annotation may unblock declaration emit. this.t = 12 + p; } diff --git a/tests/baselines/reference/jsDeclarationsExportAssignedConstructorFunctionWithSub.types b/tests/baselines/reference/jsDeclarationsExportAssignedConstructorFunctionWithSub.types index 7a738df3bb026..ce8f71cd81cfe 100644 --- a/tests/baselines/reference/jsDeclarationsExportAssignedConstructorFunctionWithSub.types +++ b/tests/baselines/reference/jsDeclarationsExportAssignedConstructorFunctionWithSub.types @@ -3,10 +3,10 @@ * @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 +>module.exports = function (p) { this.t = 12 + p;} : { (p: number): void; new (p: number): exports; Sub: typeof Sub; } +>module.exports : { (p: number): void; new (p: number): exports; Sub: typeof Sub; } +>module : { "\"tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunctionWithSub\"": { (p: number): void; new (p: number): exports; Sub: typeof Sub; }; } +>exports : { (p: number): void; new (p: number): exports; Sub: typeof Sub; } >function (p) { this.t = 12 + p;} : typeof exports >p : number @@ -22,9 +22,9 @@ module.exports = function (p) { 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 +>module.exports : { (p: number): void; new (p: number): exports; Sub: typeof Sub; } +>module : { "\"tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunctionWithSub\"": { (p: number): void; new (p: number): exports; Sub: typeof Sub; }; } +>exports : { (p: number): void; new (p: number): exports; Sub: typeof Sub; } >Sub : typeof Sub >function() { this.instance = new module.exports(10);} : typeof Sub @@ -34,18 +34,18 @@ module.exports.Sub = function() { >this : this >instance : any >new module.exports(10) : exports ->module.exports : typeof exports ->module : { "\"tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunctionWithSub\"": typeof exports; } ->exports : typeof exports +>module.exports : { (p: number): void; new (p: number): exports; Sub: typeof Sub; } +>module : { "\"tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunctionWithSub\"": { (p: number): void; new (p: number): exports; Sub: typeof Sub; }; } +>exports : { (p: number): void; new (p: number): exports; Sub: typeof Sub; } >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 +>module.exports : { (p: number): void; new (p: number): exports; Sub: typeof Sub; } +>module : { "\"tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedConstructorFunctionWithSub\"": { (p: number): void; new (p: number): exports; Sub: typeof Sub; }; } +>exports : { (p: number): void; new (p: number): exports; Sub: typeof Sub; } >Sub : typeof Sub >prototype : {} >{ } : {} diff --git a/tests/baselines/reference/jsDeclarationsFunctionClassesCjsExportAssignment.types b/tests/baselines/reference/jsDeclarationsFunctionClassesCjsExportAssignment.types index b374a4617523f..ee7c77b627dee 100644 --- a/tests/baselines/reference/jsDeclarationsFunctionClassesCjsExportAssignment.types +++ b/tests/baselines/reference/jsDeclarationsFunctionClassesCjsExportAssignment.types @@ -129,9 +129,9 @@ Context.prototype = { } } module.exports = Context; ->module.exports = Context : typeof Context ->module.exports : typeof Context ->module : { "\"tests/cases/conformance/jsdoc/declarations/context\"": typeof Context; } ->exports : typeof Context +>module.exports = Context : { (input: Input): Context; new (input: Input): Context; prototype: { construct(input: Input, handle?: (arg: Context) => void): State; }; } +>module.exports : { (input: Input): Context; new (input: Input): Context; prototype: { construct(input: Input, handle?: (arg: Context) => void): State; }; } +>module : { "\"tests/cases/conformance/jsdoc/declarations/context\"": { (input: Input): Context; new (input: Input): Context; prototype: { construct(input: Input, handle?: (arg: Context) => void): State; }; }; } +>exports : { (input: Input): Context; new (input: Input): Context; prototype: { construct(input: Input, handle?: (arg: Context) => void): State; }; } >Context : typeof Context diff --git a/tests/baselines/reference/jsdocTypeReferenceToImportOfFunctionExpression.types b/tests/baselines/reference/jsdocTypeReferenceToImportOfFunctionExpression.types index 81422f0c76c9d..bf8fe06990864 100644 --- a/tests/baselines/reference/jsdocTypeReferenceToImportOfFunctionExpression.types +++ b/tests/baselines/reference/jsdocTypeReferenceToImportOfFunctionExpression.types @@ -9,10 +9,10 @@ const MW = require("./MW"); /** @class */ module.exports = function MC() { ->module.exports = function MC() { /** @type {any} */ var x = {} return new MW(x);} : typeof MC ->module.exports : typeof MC ->module : { "\"tests/cases/conformance/jsdoc/MC\"": typeof MC; } ->exports : typeof MC +>module.exports = function MC() { /** @type {any} */ var x = {} return new MW(x);} : { (): import("tests/cases/conformance/jsdoc/MW"); new (): MC; } +>module.exports : { (): import("tests/cases/conformance/jsdoc/MW"); new (): MC; } +>module : { "\"tests/cases/conformance/jsdoc/MC\"": { (): import("tests/cases/conformance/jsdoc/MW"); new (): MC; }; } +>exports : { (): import("tests/cases/conformance/jsdoc/MW"); new (): MC; } >function MC() { /** @type {any} */ var x = {} return new MW(x);} : typeof MC >MC : typeof MC @@ -38,14 +38,14 @@ class MW { * @param {MC} compiler the compiler */ constructor(compiler) { ->compiler : typeof MC +>compiler : { (): MW; new (): MC; } this.compiler = compiler; ->this.compiler = compiler : typeof MC +>this.compiler = compiler : { (): MW; new (): MC; } >this.compiler : any >this : this >compiler : any ->compiler : typeof MC +>compiler : { (): MW; new (): MC; } } } diff --git a/tests/baselines/reference/moduleExportAssignment.types b/tests/baselines/reference/moduleExportAssignment.types index 54fe7a2e11af4..86edcb8f1490f 100644 --- a/tests/baselines/reference/moduleExportAssignment.types +++ b/tests/baselines/reference/moduleExportAssignment.types @@ -1,18 +1,18 @@ === tests/cases/conformance/salsa/use.js === var npmlog = require('./npmlog') ->npmlog : typeof EE ->require('./npmlog') : typeof EE +>npmlog : { on(s: string): void; x: number; y: number; } +>require('./npmlog') : { on(s: string): void; x: number; y: number; } >require : any >'./npmlog' : "./npmlog" npmlog.x >npmlog.x : number ->npmlog : typeof EE +>npmlog : { on(s: string): void; x: number; y: number; } >x : number npmlog.on >npmlog.on : (s: string) => void ->npmlog : typeof EE +>npmlog : { on(s: string): void; x: number; y: number; } >on : (s: string) => void === tests/cases/conformance/salsa/npmlog.js === @@ -25,55 +25,55 @@ class EE { >s : string } var npmlog = module.exports = new EE() ->npmlog : typeof EE ->module.exports = new EE() : typeof EE ->module.exports : typeof EE ->module : { "\"tests/cases/conformance/salsa/npmlog\"": typeof EE; } ->exports : typeof EE +>npmlog : { on(s: string): void; x: number; y: number; } +>module.exports = new EE() : { on(s: string): void; x: number; y: number; } +>module.exports : { on(s: string): void; x: number; y: number; } +>module : { "\"tests/cases/conformance/salsa/npmlog\"": { on(s: string): void; x: number; y: number; }; } +>exports : { on(s: string): void; x: number; y: number; } >new EE() : EE >EE : typeof EE npmlog.on('hi') // both references should see EE.on >npmlog.on('hi') : void >npmlog.on : (s: string) => void ->npmlog : typeof EE +>npmlog : { on(s: string): void; x: number; y: number; } >on : (s: string) => void >'hi' : "hi" module.exports.on('hi') // here too >module.exports.on('hi') : void >module.exports.on : (s: string) => void ->module.exports : typeof EE ->module : { "\"tests/cases/conformance/salsa/npmlog\"": typeof EE; } ->exports : typeof EE +>module.exports : { on(s: string): void; x: number; y: number; } +>module : { "\"tests/cases/conformance/salsa/npmlog\"": { on(s: string): void; x: number; y: number; }; } +>exports : { on(s: string): void; x: number; y: number; } >on : (s: string) => void >'hi' : "hi" npmlog.x = 1 >npmlog.x = 1 : 1 >npmlog.x : number ->npmlog : typeof EE +>npmlog : { on(s: string): void; x: number; y: number; } >x : number >1 : 1 module.exports.y = 2 >module.exports.y = 2 : 2 >module.exports.y : number ->module.exports : typeof EE ->module : { "\"tests/cases/conformance/salsa/npmlog\"": typeof EE; } ->exports : typeof EE +>module.exports : { on(s: string): void; x: number; y: number; } +>module : { "\"tests/cases/conformance/salsa/npmlog\"": { on(s: string): void; x: number; y: number; }; } +>exports : { on(s: string): void; x: number; y: number; } >y : number >2 : 2 npmlog.y >npmlog.y : number ->npmlog : typeof EE +>npmlog : { on(s: string): void; x: number; y: number; } >y : number module.exports.x >module.exports.x : number ->module.exports : typeof EE ->module : { "\"tests/cases/conformance/salsa/npmlog\"": typeof EE; } ->exports : typeof EE +>module.exports : { on(s: string): void; x: number; y: number; } +>module : { "\"tests/cases/conformance/salsa/npmlog\"": { on(s: string): void; x: number; y: number; }; } +>exports : { on(s: string): void; x: number; y: number; } >x : number diff --git a/tests/baselines/reference/moduleExportAssignment5.types b/tests/baselines/reference/moduleExportAssignment5.types index b4b6370be075c..07f36a230b204 100644 --- a/tests/baselines/reference/moduleExportAssignment5.types +++ b/tests/baselines/reference/moduleExportAssignment5.types @@ -20,18 +20,18 @@ axios.m() >m : () => void module.exports = axios; ->module.exports = axios : typeof Axios ->module.exports : typeof Axios ->module : { "\"tests/cases/conformance/salsa/axios\"": typeof Axios; } ->exports : typeof Axios +>module.exports = axios : { m(): void; default: Axios; } +>module.exports : { m(): void; default: Axios; } +>module : { "\"tests/cases/conformance/salsa/axios\"": { m(): void; default: Axios; }; } +>exports : { m(): void; default: Axios; } >axios : Axios module.exports.default = axios; >module.exports.default = axios : Axios >module.exports.default : Axios ->module.exports : typeof Axios ->module : { "\"tests/cases/conformance/salsa/axios\"": typeof Axios; } ->exports : typeof Axios +>module.exports : { m(): void; default: Axios; } +>module : { "\"tests/cases/conformance/salsa/axios\"": { m(): void; default: Axios; }; } +>exports : { m(): void; default: Axios; } >default : Axios >axios : Axios diff --git a/tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedClassInstance1.ts b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedClassInstance1.ts new file mode 100644 index 0000000000000..5f5796089dc27 --- /dev/null +++ b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedClassInstance1.ts @@ -0,0 +1,9 @@ +// @allowJs: true +// @checkJs: true +// @target: es5 +// @outDir: ./out +// @declaration: true +// @filename: index.js +class Foo {} + +module.exports = new Foo(); \ No newline at end of file diff --git a/tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedClassInstance2.ts b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedClassInstance2.ts new file mode 100644 index 0000000000000..aa0f37ea41a3d --- /dev/null +++ b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedClassInstance2.ts @@ -0,0 +1,12 @@ +// @allowJs: true +// @checkJs: true +// @target: es5 +// @outDir: ./out +// @declaration: true +// @filename: index.js +class Foo { + static stat = 10; + member = 10; +} + +module.exports = new Foo(); \ No newline at end of file diff --git a/tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedClassInstance3.ts b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedClassInstance3.ts new file mode 100644 index 0000000000000..309654c867397 --- /dev/null +++ b/tests/cases/conformance/jsdoc/declarations/jsDeclarationsExportAssignedClassInstance3.ts @@ -0,0 +1,14 @@ +// @allowJs: true +// @checkJs: true +// @target: es5 +// @outDir: ./out +// @declaration: true +// @filename: index.js +class Foo { + static stat = 10; + member = 10; +} + +module.exports = new Foo(); + +module.exports.additional = 20; \ No newline at end of file