Skip to content

Commit 703dcee

Browse files
committed
Allow private and protected class members to be accessible in nested classes
1 parent d92f78d commit 703dcee

1 file changed

Lines changed: 14 additions & 8 deletions

File tree

src/compiler/checker.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8950,9 +8950,10 @@ namespace ts {
89508950

89518951
const enclosingClass = enclosingClassDeclaration ? <InterfaceType>getDeclaredTypeOfSymbol(getSymbolOfNode(enclosingClassDeclaration)) : undefined;
89528952

8953-
// Private property is accessible if declaring and enclosing class are the same
8953+
// Private property is accessible if the property is within the declaring class
89548954
if (flags & NodeFlags.Private) {
8955-
if (declaringClass !== enclosingClass) {
8955+
const declaringClassDeclaration = <ClassLikeDeclaration>getClassLikeDeclarationOfSymbol(getParentOfSymbol(prop));
8956+
if (!isNodeWithinClass(node, declaringClassDeclaration)) {
89568957
error(node, Diagnostics.Property_0_is_private_and_only_accessible_within_class_1, symbolToString(prop), typeToString(declaringClass));
89578958
return false;
89588959
}
@@ -8965,10 +8966,13 @@ namespace ts {
89658966
if (left.kind === SyntaxKind.SuperKeyword) {
89668967
return true;
89678968
}
8968-
// A protected property is accessible in the declaring class and classes derived from it
8969+
// A protected property is accessible if the property is within the declaring class or classes derived from it
8970+
const typeClassDeclaration = <ClassLikeDeclaration>getClassLikeDeclarationOfSymbol(type.symbol);
89698971
if (!enclosingClass || !hasBaseType(enclosingClass, declaringClass)) {
8970-
error(node, Diagnostics.Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses, symbolToString(prop), typeToString(declaringClass));
8971-
return false;
8972+
if (!isNodeWithinClass(node, typeClassDeclaration)) {
8973+
error(node, Diagnostics.Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses, symbolToString(prop), typeToString(declaringClass));
8974+
return false;
8975+
}
89728976
}
89738977
// No further restrictions for static properties
89748978
if (flags & NodeFlags.Static) {
@@ -8981,9 +8985,11 @@ namespace ts {
89818985
}
89828986

89838987
// TODO: why is the first part of this check here?
8984-
if (!(getTargetType(type).flags & (TypeFlags.Class | TypeFlags.Interface) && hasBaseType(<InterfaceType>type, enclosingClass))) {
8985-
error(node, Diagnostics.Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1, symbolToString(prop), typeToString(enclosingClass));
8986-
return false;
8988+
if (getTargetType(type).flags & (TypeFlags.Class | TypeFlags.Interface)) {
8989+
if (!(hasBaseType(<InterfaceType>type, enclosingClass) || isNodeWithinClass(node, typeClassDeclaration))) {
8990+
error(node, Diagnostics.Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1, symbolToString(prop), typeToString(enclosingClass));
8991+
return false;
8992+
}
89878993
}
89888994
return true;
89898995
}

0 commit comments

Comments
 (0)