diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index d7ad2c3a78d..3c02fc634b5 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -1266,7 +1266,9 @@ namespace ts { Diagnostics.Exported_variable_0_has_or_is_using_private_name_1; } // This check is to ensure we don't report error on constructor parameter property as that error would be reported during parameter emit - else if (node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature) { + // The only exception here is if the constructor was marked as private. we are not emitting the constructor paramters at all. + else if (node.kind === SyntaxKind.PropertyDeclaration || node.kind === SyntaxKind.PropertySignature || + (node.kind === SyntaxKind.Parameter && hasModifier(node.parent, ModifierFlags.Private))) { // TODO(jfreeman): Deal with computed properties in error reporting. if (hasModifier(node, ModifierFlags.Static)) { return symbolAccessibilityResult.errorModuleName ? @@ -1275,7 +1277,7 @@ namespace ts { Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_name_1_from_private_module_2 : Diagnostics.Public_static_property_0_of_exported_class_has_or_is_using_private_name_1; } - else if (node.parent.kind === SyntaxKind.ClassDeclaration) { + else if (node.parent.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.Parameter) { return symbolAccessibilityResult.errorModuleName ? symbolAccessibilityResult.accessibility === SymbolAccessibility.CannotBeNamed ? Diagnostics.Public_property_0_of_exported_class_has_or_is_using_name_1_from_external_module_2_but_cannot_be_named : @@ -1501,6 +1503,11 @@ namespace ts { write("["); } else { + if (node.kind === SyntaxKind.Constructor && hasModifier(node, ModifierFlags.Private)) { + write("();"); + writeLine(); + return; + } // Construct signature or constructor type write new Signature if (node.kind === SyntaxKind.ConstructSignature || node.kind === SyntaxKind.ConstructorType) { write("new "); diff --git a/tests/baselines/reference/classConstructorAccessibility.js b/tests/baselines/reference/classConstructorAccessibility.js index 46a548d0b54..4d120a3980f 100644 --- a/tests/baselines/reference/classConstructorAccessibility.js +++ b/tests/baselines/reference/classConstructorAccessibility.js @@ -89,7 +89,7 @@ declare class C { } declare class D { x: number; - private constructor(x); + private constructor(); } declare class E { x: number; diff --git a/tests/baselines/reference/classConstructorAccessibility2.js b/tests/baselines/reference/classConstructorAccessibility2.js index 7297af11a4e..76c8ea19110 100644 --- a/tests/baselines/reference/classConstructorAccessibility2.js +++ b/tests/baselines/reference/classConstructorAccessibility2.js @@ -135,7 +135,7 @@ declare class BaseB { } declare class BaseC { x: number; - private constructor(x); + private constructor(); createInstance(): void; static staticInstance(): void; } diff --git a/tests/baselines/reference/classConstructorAccessibility3.js b/tests/baselines/reference/classConstructorAccessibility3.js index 3e024970bcf..d1bd8f38c40 100644 --- a/tests/baselines/reference/classConstructorAccessibility3.js +++ b/tests/baselines/reference/classConstructorAccessibility3.js @@ -90,7 +90,7 @@ declare class Baz { } declare class Qux { x: number; - private constructor(x); + private constructor(); } declare let a: typeof Foo; declare let b: typeof Baz; diff --git a/tests/baselines/reference/classConstructorOverloadsAccessibility.js b/tests/baselines/reference/classConstructorOverloadsAccessibility.js index 7fef7443c62..2a173966d5d 100644 --- a/tests/baselines/reference/classConstructorOverloadsAccessibility.js +++ b/tests/baselines/reference/classConstructorOverloadsAccessibility.js @@ -59,7 +59,7 @@ var D = (function () { declare class A { constructor(a: boolean); protected constructor(a: number); - private constructor(a); + private constructor(); } declare class B { protected constructor(a: number); diff --git a/tests/baselines/reference/declarationEmitClassPrivateConstructor.js b/tests/baselines/reference/declarationEmitClassPrivateConstructor.js new file mode 100644 index 00000000000..6cc65964987 --- /dev/null +++ b/tests/baselines/reference/declarationEmitClassPrivateConstructor.js @@ -0,0 +1,72 @@ +//// [declarationEmitClassPrivateConstructor.ts] +interface PrivateInterface { +} + +export class ExportedClass1 { + private constructor(data: PrivateInterface) { } +} + +export class ExportedClass2 { + private constructor(private data: PrivateInterface) { } +} + +export class ExportedClass3 { + private constructor(private data: PrivateInterface, private n: number) { } +} + +export class ExportedClass4 { + private constructor(private data: PrivateInterface, public n:number) { } +} + +//// [declarationEmitClassPrivateConstructor.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var ExportedClass1 = (function () { + function ExportedClass1(data) { + } + return ExportedClass1; +}()); +exports.ExportedClass1 = ExportedClass1; +var ExportedClass2 = (function () { + function ExportedClass2(data) { + this.data = data; + } + return ExportedClass2; +}()); +exports.ExportedClass2 = ExportedClass2; +var ExportedClass3 = (function () { + function ExportedClass3(data, n) { + this.data = data; + this.n = n; + } + return ExportedClass3; +}()); +exports.ExportedClass3 = ExportedClass3; +var ExportedClass4 = (function () { + function ExportedClass4(data, n) { + this.data = data; + this.n = n; + } + return ExportedClass4; +}()); +exports.ExportedClass4 = ExportedClass4; + + +//// [declarationEmitClassPrivateConstructor.d.ts] +export declare class ExportedClass1 { + private constructor(); +} +export declare class ExportedClass2 { + private data; + private constructor(); +} +export declare class ExportedClass3 { + private data; + private n; + private constructor(); +} +export declare class ExportedClass4 { + private data; + n: number; + private constructor(); +} diff --git a/tests/baselines/reference/declarationEmitClassPrivateConstructor.symbols b/tests/baselines/reference/declarationEmitClassPrivateConstructor.symbols new file mode 100644 index 00000000000..285d9fb3f39 --- /dev/null +++ b/tests/baselines/reference/declarationEmitClassPrivateConstructor.symbols @@ -0,0 +1,38 @@ +=== tests/cases/compiler/declarationEmitClassPrivateConstructor.ts === +interface PrivateInterface { +>PrivateInterface : Symbol(PrivateInterface, Decl(declarationEmitClassPrivateConstructor.ts, 0, 0)) +} + +export class ExportedClass1 { +>ExportedClass1 : Symbol(ExportedClass1, Decl(declarationEmitClassPrivateConstructor.ts, 1, 1)) + + private constructor(data: PrivateInterface) { } +>data : Symbol(data, Decl(declarationEmitClassPrivateConstructor.ts, 4, 24)) +>PrivateInterface : Symbol(PrivateInterface, Decl(declarationEmitClassPrivateConstructor.ts, 0, 0)) +} + +export class ExportedClass2 { +>ExportedClass2 : Symbol(ExportedClass2, Decl(declarationEmitClassPrivateConstructor.ts, 5, 1)) + + private constructor(private data: PrivateInterface) { } +>data : Symbol(ExportedClass2.data, Decl(declarationEmitClassPrivateConstructor.ts, 8, 24)) +>PrivateInterface : Symbol(PrivateInterface, Decl(declarationEmitClassPrivateConstructor.ts, 0, 0)) +} + +export class ExportedClass3 { +>ExportedClass3 : Symbol(ExportedClass3, Decl(declarationEmitClassPrivateConstructor.ts, 9, 1)) + + private constructor(private data: PrivateInterface, private n: number) { } +>data : Symbol(ExportedClass3.data, Decl(declarationEmitClassPrivateConstructor.ts, 12, 24)) +>PrivateInterface : Symbol(PrivateInterface, Decl(declarationEmitClassPrivateConstructor.ts, 0, 0)) +>n : Symbol(ExportedClass3.n, Decl(declarationEmitClassPrivateConstructor.ts, 12, 55)) +} + +export class ExportedClass4 { +>ExportedClass4 : Symbol(ExportedClass4, Decl(declarationEmitClassPrivateConstructor.ts, 13, 1)) + + private constructor(private data: PrivateInterface, public n:number) { } +>data : Symbol(ExportedClass4.data, Decl(declarationEmitClassPrivateConstructor.ts, 16, 24)) +>PrivateInterface : Symbol(PrivateInterface, Decl(declarationEmitClassPrivateConstructor.ts, 0, 0)) +>n : Symbol(ExportedClass4.n, Decl(declarationEmitClassPrivateConstructor.ts, 16, 55)) +} diff --git a/tests/baselines/reference/declarationEmitClassPrivateConstructor.types b/tests/baselines/reference/declarationEmitClassPrivateConstructor.types new file mode 100644 index 00000000000..ed8d5494ba6 --- /dev/null +++ b/tests/baselines/reference/declarationEmitClassPrivateConstructor.types @@ -0,0 +1,38 @@ +=== tests/cases/compiler/declarationEmitClassPrivateConstructor.ts === +interface PrivateInterface { +>PrivateInterface : PrivateInterface +} + +export class ExportedClass1 { +>ExportedClass1 : ExportedClass1 + + private constructor(data: PrivateInterface) { } +>data : PrivateInterface +>PrivateInterface : PrivateInterface +} + +export class ExportedClass2 { +>ExportedClass2 : ExportedClass2 + + private constructor(private data: PrivateInterface) { } +>data : PrivateInterface +>PrivateInterface : PrivateInterface +} + +export class ExportedClass3 { +>ExportedClass3 : ExportedClass3 + + private constructor(private data: PrivateInterface, private n: number) { } +>data : PrivateInterface +>PrivateInterface : PrivateInterface +>n : number +} + +export class ExportedClass4 { +>ExportedClass4 : ExportedClass4 + + private constructor(private data: PrivateInterface, public n:number) { } +>data : PrivateInterface +>PrivateInterface : PrivateInterface +>n : number +} diff --git a/tests/baselines/reference/declarationEmitClassPrivateConstructor2.errors.txt b/tests/baselines/reference/declarationEmitClassPrivateConstructor2.errors.txt new file mode 100644 index 00000000000..a31454a4760 --- /dev/null +++ b/tests/baselines/reference/declarationEmitClassPrivateConstructor2.errors.txt @@ -0,0 +1,20 @@ +tests/cases/compiler/declarationEmitClassPrivateConstructor2.ts(5,38): error TS4031: Public property 'data' of exported class has or is using private name 'PrivateInterface'. +tests/cases/compiler/declarationEmitClassPrivateConstructor2.ts(10,33): error TS4063: Parameter 'data' of constructor from exported class has or is using private name 'PrivateInterface'. + + +==== tests/cases/compiler/declarationEmitClassPrivateConstructor2.ts (2 errors) ==== + interface PrivateInterface { + } + + export class ExportedClass1 { + private constructor(public data: PrivateInterface) { } + ~~~~~~~~~~~~~~~~ +!!! error TS4031: Public property 'data' of exported class has or is using private name 'PrivateInterface'. + } + + + export class ExportedClass2 { + protected constructor(data: PrivateInterface) { } + ~~~~~~~~~~~~~~~~ +!!! error TS4063: Parameter 'data' of constructor from exported class has or is using private name 'PrivateInterface'. + } \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmitClassPrivateConstructor2.js b/tests/baselines/reference/declarationEmitClassPrivateConstructor2.js new file mode 100644 index 00000000000..8b7ad25a6bf --- /dev/null +++ b/tests/baselines/reference/declarationEmitClassPrivateConstructor2.js @@ -0,0 +1,29 @@ +//// [declarationEmitClassPrivateConstructor2.ts] +interface PrivateInterface { +} + +export class ExportedClass1 { + private constructor(public data: PrivateInterface) { } +} + + +export class ExportedClass2 { + protected constructor(data: PrivateInterface) { } +} + +//// [declarationEmitClassPrivateConstructor2.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var ExportedClass1 = (function () { + function ExportedClass1(data) { + this.data = data; + } + return ExportedClass1; +}()); +exports.ExportedClass1 = ExportedClass1; +var ExportedClass2 = (function () { + function ExportedClass2(data) { + } + return ExportedClass2; +}()); +exports.ExportedClass2 = ExportedClass2; diff --git a/tests/baselines/reference/typesWithPrivateConstructor.js b/tests/baselines/reference/typesWithPrivateConstructor.js index be58c77339d..e5c59b99e93 100644 --- a/tests/baselines/reference/typesWithPrivateConstructor.js +++ b/tests/baselines/reference/typesWithPrivateConstructor.js @@ -38,7 +38,7 @@ declare class C { declare var c: any; declare var r: () => void; declare class C2 { - private constructor(x); + private constructor(); } declare var c2: any; declare var r2: (x: number) => void; diff --git a/tests/cases/compiler/declarationEmitClassPrivateConstructor.ts b/tests/cases/compiler/declarationEmitClassPrivateConstructor.ts new file mode 100644 index 00000000000..d77360496c9 --- /dev/null +++ b/tests/cases/compiler/declarationEmitClassPrivateConstructor.ts @@ -0,0 +1,22 @@ +// @target: es5 +// @module: commonjs +// @declaration: true + +interface PrivateInterface { +} + +export class ExportedClass1 { + private constructor(data: PrivateInterface) { } +} + +export class ExportedClass2 { + private constructor(private data: PrivateInterface) { } +} + +export class ExportedClass3 { + private constructor(private data: PrivateInterface, private n: number) { } +} + +export class ExportedClass4 { + private constructor(private data: PrivateInterface, public n:number) { } +} \ No newline at end of file diff --git a/tests/cases/compiler/declarationEmitClassPrivateConstructor2.ts b/tests/cases/compiler/declarationEmitClassPrivateConstructor2.ts new file mode 100644 index 00000000000..900ece84f8e --- /dev/null +++ b/tests/cases/compiler/declarationEmitClassPrivateConstructor2.ts @@ -0,0 +1,15 @@ +// @target: es5 +// @module: commonjs +// @declaration: true + +interface PrivateInterface { +} + +export class ExportedClass1 { + private constructor(public data: PrivateInterface) { } +} + + +export class ExportedClass2 { + protected constructor(data: PrivateInterface) { } +} \ No newline at end of file