diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 91346429b1774..e3839d38521f0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -33621,7 +33621,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { * @param prop The symbol for the property being accessed. */ function checkPropertyAccessibility( - node: PropertyAccessExpression | QualifiedName | PropertyAccessExpression | VariableDeclaration | ParameterDeclaration | ImportTypeNode | PropertyAssignment | ShorthandPropertyAssignment | BindingElement, + node: PropertyAccessExpression | QualifiedName | ElementAccessExpression | VariableDeclaration | ParameterDeclaration | ImportTypeNode | PropertyAssignment | ShorthandPropertyAssignment | BindingElement, isSuper: boolean, writing: boolean, type: Type, @@ -33631,7 +33631,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const errorNode = !reportError ? undefined : node.kind === SyntaxKind.QualifiedName ? node.right : node.kind === SyntaxKind.ImportType ? node : - node.kind === SyntaxKind.BindingElement && node.propertyName ? node.propertyName : node.name; + node.kind === SyntaxKind.BindingElement && node.propertyName ? node.propertyName : + node.kind === SyntaxKind.ElementAccessExpression ? node.expression : node.name; return checkPropertyAccessibilityAtLocation(node, isSuper, writing, type, prop, errorNode); } @@ -34740,7 +34741,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } const indexedAccessType = getIndexedAccessTypeOrUndefined(objectType, effectiveIndexType, accessFlags, node) || errorType; - return checkIndexedAccessIndexType(getFlowTypeOfAccessExpression(node, getNodeLinks(node).resolvedSymbol, indexedAccessType, indexExpression, checkMode), node); + const symbol = getNodeLinks(node).resolvedSymbol; + if (symbol) { + const apparentType = getApparentType(objectType); + checkPropertyAccessibility(node, node.expression.kind === SyntaxKind.SuperKeyword, !!(accessFlags & AccessFlags.Writing), apparentType, symbol); + } + return checkIndexedAccessIndexType(getFlowTypeOfAccessExpression(node, symbol, indexedAccessType, indexExpression, checkMode), node); } function callLikeExpressionMayHaveTypeArguments(node: CallLikeExpression): node is CallExpression | NewExpression | TaggedTemplateExpression | JsxOpeningElement { diff --git a/tests/baselines/reference/keyofAndIndexedAccess.errors.txt b/tests/baselines/reference/keyofAndIndexedAccess.errors.txt index e833106df6fe5..a4371bccc7afe 100644 --- a/tests/baselines/reference/keyofAndIndexedAccess.errors.txt +++ b/tests/baselines/reference/keyofAndIndexedAccess.errors.txt @@ -1,3 +1,5 @@ +keyofAndIndexedAccess.ts(176,16): error TS2445: Property 'y' is protected and only accessible within class 'C' and its subclasses. +keyofAndIndexedAccess.ts(177,16): error TS2341: Property 'z' is private and only accessible within class 'C'. keyofAndIndexedAccess.ts(205,24): error TS2322: Type 'T[keyof T]' is not assignable to type 'object'. Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'object'. Type 'T[string]' is not assignable to type 'object'. @@ -15,7 +17,7 @@ keyofAndIndexedAccess.ts(318,5): error TS2322: Type 'T[K]' is not assignable to Type 'T[string]' is not assignable to type '{}'. -==== keyofAndIndexedAccess.ts (5 errors) ==== +==== keyofAndIndexedAccess.ts (7 errors) ==== class Shape { name: string; width: number; @@ -192,7 +194,11 @@ keyofAndIndexedAccess.ts(318,5): error TS2322: Type 'T[K]' is not assignable to type Z = C["z"]; let x: X = c["x"]; let y: Y = c["y"]; + ~ +!!! error TS2445: Property 'y' is protected and only accessible within class 'C' and its subclasses. let z: Z = c["z"]; + ~ +!!! error TS2341: Property 'z' is private and only accessible within class 'C'. } function f50(k: keyof T, s: string) { diff --git a/tests/baselines/reference/superElementAccess.errors.txt b/tests/baselines/reference/superElementAccess.errors.txt new file mode 100644 index 0000000000000..c34ffabf1b48d --- /dev/null +++ b/tests/baselines/reference/superElementAccess.errors.txt @@ -0,0 +1,56 @@ +superElementAccess.ts(21,9): error TS2340: Only public and protected methods of the base class are accessible via the 'super' keyword. +superElementAccess.ts(23,9): error TS2341: Property 'p1' is private and only accessible within class 'MyBase'. +superElementAccess.ts(25,18): error TS2340: Only public and protected methods of the base class are accessible via the 'super' keyword. +superElementAccess.ts(27,18): error TS2340: Only public and protected methods of the base class are accessible via the 'super' keyword. +superElementAccess.ts(31,9): error TS2340: Only public and protected methods of the base class are accessible via the 'super' keyword. +superElementAccess.ts(33,17): error TS2340: Only public and protected methods of the base class are accessible via the 'super' keyword. + + +==== superElementAccess.ts (6 errors) ==== + class MyBase { + m1(a: string) { return a; } + private p1() { } + m2: () => void = function () { } + d1: number = 42; + private d2: number = 42; + get value() {return 0 } + set value(v: number) { } + } + + + class MyDerived extends MyBase { + + foo() { + super["m1"]("hi"); // Should be allowed, method on base prototype + + var l2 = super["m1"].bind(this); // Should be allowed, can access properties as well as invoke + + var x: (a: string) => string = super["m1"]; // Should be allowed, can assign to var with compatible signature + + super["m2"].bind(this); // Should error, instance property, not a public instance member function + ~~~~~ +!!! error TS2340: Only public and protected methods of the base class are accessible via the 'super' keyword. + + super["p1"](); // Should error, private not public instance member function + ~~~~~ +!!! error TS2341: Property 'p1' is private and only accessible within class 'MyBase'. + + var l1 = super["d1"]; // Should error, instance data property not a public instance member function + ~~~~~ +!!! error TS2340: Only public and protected methods of the base class are accessible via the 'super' keyword. + + var l1 = super["d2"]; // Should error, instance data property not a public instance member function + ~~~~~ +!!! error TS2340: Only public and protected methods of the base class are accessible via the 'super' keyword. + + super["m1"] = function (a: string) { return ""; }; // Should be allowed, we will not restrict assignment + + super["value"] = 0; // Should error, instance data property not a public instance member function + ~~~~~ +!!! error TS2340: Only public and protected methods of the base class are accessible via the 'super' keyword. + + var z = super["value"]; // Should error, instance data property not a public instance member function + ~~~~~ +!!! error TS2340: Only public and protected methods of the base class are accessible via the 'super' keyword. + } + } \ No newline at end of file diff --git a/tests/baselines/reference/superElementAccess.types b/tests/baselines/reference/superElementAccess.types index 80aa6983493c2..c2698dc9e402e 100644 --- a/tests/baselines/reference/superElementAccess.types +++ b/tests/baselines/reference/superElementAccess.types @@ -73,7 +73,9 @@ class MyDerived extends MyBase { var l2 = super["m1"].bind(this); // Should be allowed, can access properties as well as invoke >l2 : any +> : ^^^ >super["m1"].bind(this) : any +> : ^^^ >super["m1"].bind : (this: Function, thisArg: any, ...argArray: any[]) => any > : ^ ^^ ^^ ^^ ^^^^^ ^^ ^^^^^ >super["m1"] : (a: string) => string @@ -101,6 +103,7 @@ class MyDerived extends MyBase { super["m2"].bind(this); // Should error, instance property, not a public instance member function >super["m2"].bind(this) : any +> : ^^^ >super["m2"].bind : (this: Function, thisArg: any, ...argArray: any[]) => any > : ^ ^^ ^^ ^^ ^^^^^ ^^ ^^^^^ >super["m2"] : () => void