Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Protected constructors now accessible everywhere in subclasses
  • Loading branch information
sandersn committed Jul 23, 2016
commit 2169928f2b651d02f5eadada496c823e6bd9a310
7 changes: 2 additions & 5 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11544,18 +11544,15 @@ namespace ts {
const declaringClassDeclaration = <ClassLikeDeclaration>getClassLikeDeclarationOfSymbol(declaration.parent.symbol);
const declaringClass = <InterfaceType>getDeclaredTypeOfSymbol(declaration.parent.symbol);

// A private or protected constructor can only be instantiated within its own class or a static method of a subclass
// A private or protected constructor can only be instantiated within its own class (or a subclass, for protected)
if (!isNodeWithinClass(node, declaringClassDeclaration)) {
const containingFunction = getContainingFunction(node);
const containingClass = getContainingClass(node);
if (containingClass) {
const containingType = getTypeOfNode(containingClass);
const baseTypes = getBaseTypes(<InterfaceType>containingType);
if (baseTypes.length) {
const baseType = baseTypes[0];
if (containingFunction &&
containingFunction.flags & NodeFlags.Static &&
flags & NodeFlags.Protected &&
if (flags & NodeFlags.Protected &&
baseType.symbol === declaration.parent.symbol) {
return true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does it matter whether the function is static?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops. I wasn't paying attention and overfit to the example. I see that instance methods should be ok based on your constructor-with-super equivalence example.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
tests/cases/conformance/classes/constructorDeclarations/classConstructorAccessibility2.ts(28,28): error TS2674: Constructor of class 'BaseB' is protected and only accessible within the class declaration.
tests/cases/conformance/classes/constructorDeclarations/classConstructorAccessibility2.ts(32,24): error TS2675: Cannot extend a class 'BaseC'. Class constructor is marked as private.
tests/cases/conformance/classes/constructorDeclarations/classConstructorAccessibility2.ts(35,28): error TS2673: Constructor of class 'BaseC' is private and only accessible within the class declaration.
tests/cases/conformance/classes/constructorDeclarations/classConstructorAccessibility2.ts(36,35): error TS2673: Constructor of class 'BaseC' is private and only accessible within the class declaration.
tests/cases/conformance/classes/constructorDeclarations/classConstructorAccessibility2.ts(40,10): error TS2674: Constructor of class 'BaseB' is protected and only accessible within the class declaration.
tests/cases/conformance/classes/constructorDeclarations/classConstructorAccessibility2.ts(41,10): error TS2673: Constructor of class 'BaseC' is private and only accessible within the class declaration.


==== tests/cases/conformance/classes/constructorDeclarations/classConstructorAccessibility2.ts (6 errors) ====
==== tests/cases/conformance/classes/constructorDeclarations/classConstructorAccessibility2.ts (5 errors) ====

class BaseA {
public constructor(public x: number) { }
Expand Down Expand Up @@ -34,9 +33,7 @@ tests/cases/conformance/classes/constructorDeclarations/classConstructorAccessib
class DerivedB extends BaseB {
constructor(public x: number) { super(x); }
createInstance() { new DerivedB(7); }
createBaseInstance() { new BaseB(8); } // error
~~~~~~~~~~~~
!!! error TS2674: Constructor of class 'BaseB' is protected and only accessible within the class declaration.
createBaseInstance() { new BaseB(8); } // ok
static staticBaseInstance() { new BaseB(9); } // ok
}

Expand Down
4 changes: 2 additions & 2 deletions tests/baselines/reference/classConstructorAccessibility2.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class DerivedA extends BaseA {
class DerivedB extends BaseB {
constructor(public x: number) { super(x); }
createInstance() { new DerivedB(7); }
createBaseInstance() { new BaseB(8); } // error
createBaseInstance() { new BaseB(8); } // ok
static staticBaseInstance() { new BaseB(9); } // ok
}

Expand Down Expand Up @@ -92,7 +92,7 @@ var DerivedB = (function (_super) {
this.x = x;
}
DerivedB.prototype.createInstance = function () { new DerivedB(7); };
DerivedB.prototype.createBaseInstance = function () { new BaseB(8); }; // error
DerivedB.prototype.createBaseInstance = function () { new BaseB(8); }; // ok
DerivedB.staticBaseInstance = function () { new BaseB(9); }; // ok
return DerivedB;
}(BaseB));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class DerivedA extends BaseA {
class DerivedB extends BaseB {
constructor(public x: number) { super(x); }
createInstance() { new DerivedB(7); }
createBaseInstance() { new BaseB(8); } // error
createBaseInstance() { new BaseB(8); } // ok
static staticBaseInstance() { new BaseB(9); } // ok
}

Expand Down