mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 16:38:05 -06:00
Fix crash when this is typed as a generic T with no type constraints (#47991)
* fix this type validations for protected fields * update previous baselines * add new tests and baselines * ClassOrInterface can be returned as enclosingClass * inline function code and remove unnecessary blank lines * refactor enclosingClass checks
This commit is contained in:
parent
82fc9b19ba
commit
857889a4e6
@ -20644,7 +20644,7 @@ namespace ts {
|
||||
|
||||
// Return true if the given class derives from each of the declaring classes of the protected
|
||||
// constituents of the given property.
|
||||
function isClassDerivedFromDeclaringClasses(checkClass: Type, prop: Symbol, writing: boolean) {
|
||||
function isClassDerivedFromDeclaringClasses<T extends Type>(checkClass: T, prop: Symbol, writing: boolean) {
|
||||
return forEachProperty(prop, p => getDeclarationModifierFlagsFromSymbol(p, writing) & ModifierFlags.Protected ?
|
||||
!hasBaseType(checkClass, getDeclaringClass(p)) : false) ? undefined : checkClass;
|
||||
}
|
||||
@ -28396,14 +28396,15 @@ namespace ts {
|
||||
// of the property as base classes
|
||||
let enclosingClass = forEachEnclosingClass(location, enclosingDeclaration => {
|
||||
const enclosingClass = getDeclaredTypeOfSymbol(getSymbolOfNode(enclosingDeclaration)!) as InterfaceType;
|
||||
return isClassDerivedFromDeclaringClasses(enclosingClass, prop, writing) ? enclosingClass : undefined;
|
||||
return isClassDerivedFromDeclaringClasses(enclosingClass, prop, writing);
|
||||
});
|
||||
// A protected property is accessible if the property is within the declaring class or classes derived from it
|
||||
if (!enclosingClass) {
|
||||
// allow PropertyAccessibility if context is in function with this parameter
|
||||
// static member access is disallow
|
||||
let thisParameter: ParameterDeclaration | undefined;
|
||||
if (flags & ModifierFlags.Static || !(thisParameter = getThisParameterFromNodeContext(location)) || !thisParameter.type) {
|
||||
// static member access is disallowed
|
||||
enclosingClass = getEnclosingClassFromThisParameter(location);
|
||||
enclosingClass = enclosingClass && isClassDerivedFromDeclaringClasses(enclosingClass, prop, writing);
|
||||
if (flags & ModifierFlags.Static || !enclosingClass) {
|
||||
if (errorNode) {
|
||||
error(errorNode,
|
||||
Diagnostics.Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses,
|
||||
@ -28412,9 +28413,6 @@ namespace ts {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const thisType = getTypeFromTypeNode(thisParameter.type);
|
||||
enclosingClass = (((thisType.flags & TypeFlags.TypeParameter) ? getConstraintOfTypeParameter(thisType as TypeParameter) : thisType) as TypeReference).target;
|
||||
}
|
||||
// No further restrictions for static properties
|
||||
if (flags & ModifierFlags.Static) {
|
||||
@ -28435,6 +28433,18 @@ namespace ts {
|
||||
return true;
|
||||
}
|
||||
|
||||
function getEnclosingClassFromThisParameter(node: Node): InterfaceType | undefined {
|
||||
const thisParameter = getThisParameterFromNodeContext(node);
|
||||
let thisType = thisParameter?.type && getTypeFromTypeNode(thisParameter.type);
|
||||
if (thisType && thisType.flags & TypeFlags.TypeParameter) {
|
||||
thisType = getConstraintOfTypeParameter(thisType as TypeParameter);
|
||||
}
|
||||
if (thisType && getObjectFlags(thisType) & (ObjectFlags.ClassOrInterface | ObjectFlags.Reference)) {
|
||||
return getTargetType(thisType) as InterfaceType;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getThisParameterFromNodeContext(node: Node) {
|
||||
const thisContainer = getThisContainer(node, /* includeArrowFunctions */ false);
|
||||
return thisContainer && isFunctionLike(thisContainer) ? getThisParameter(thisContainer) : undefined;
|
||||
|
||||
@ -0,0 +1,147 @@
|
||||
tests/cases/compiler/protectedMembersThisParameter.ts(9,9): error TS2445: Property 'secret' is protected and only accessible within class 'Message' and its subclasses.
|
||||
tests/cases/compiler/protectedMembersThisParameter.ts(30,7): error TS2445: Property 'b' is protected and only accessible within class 'B' and its subclasses.
|
||||
tests/cases/compiler/protectedMembersThisParameter.ts(41,7): error TS2446: Property 'a' is protected and only accessible through an instance of class 'C'. This is an instance of class 'B'.
|
||||
tests/cases/compiler/protectedMembersThisParameter.ts(42,7): error TS2445: Property 'b' is protected and only accessible within class 'B' and its subclasses.
|
||||
tests/cases/compiler/protectedMembersThisParameter.ts(46,7): error TS2445: Property 'a' is protected and only accessible within class 'A' and its subclasses.
|
||||
tests/cases/compiler/protectedMembersThisParameter.ts(47,7): error TS2445: Property 'b' is protected and only accessible within class 'B' and its subclasses.
|
||||
tests/cases/compiler/protectedMembersThisParameter.ts(51,7): error TS2445: Property 'a' is protected and only accessible within class 'A' and its subclasses.
|
||||
tests/cases/compiler/protectedMembersThisParameter.ts(52,7): error TS2445: Property 'b' is protected and only accessible within class 'B' and its subclasses.
|
||||
tests/cases/compiler/protectedMembersThisParameter.ts(55,7): error TS2445: Property 'a' is protected and only accessible within class 'A' and its subclasses.
|
||||
tests/cases/compiler/protectedMembersThisParameter.ts(56,7): error TS2445: Property 'b' is protected and only accessible within class 'B' and its subclasses.
|
||||
tests/cases/compiler/protectedMembersThisParameter.ts(64,9): error TS2445: Property 'd1' is protected and only accessible within class 'D1' and its subclasses.
|
||||
tests/cases/compiler/protectedMembersThisParameter.ts(68,9): error TS2445: Property 'd1' is protected and only accessible within class 'D1' and its subclasses.
|
||||
tests/cases/compiler/protectedMembersThisParameter.ts(76,9): error TS2445: Property 'd' is protected and only accessible within class 'D2' and its subclasses.
|
||||
tests/cases/compiler/protectedMembersThisParameter.ts(77,9): error TS2445: Property 'd2' is protected and only accessible within class 'D2' and its subclasses.
|
||||
tests/cases/compiler/protectedMembersThisParameter.ts(80,9): error TS2445: Property 'd' is protected and only accessible within class 'D2' and its subclasses.
|
||||
tests/cases/compiler/protectedMembersThisParameter.ts(81,9): error TS2445: Property 'd2' is protected and only accessible within class 'D2' and its subclasses.
|
||||
|
||||
|
||||
==== tests/cases/compiler/protectedMembersThisParameter.ts (16 errors) ====
|
||||
class Message {
|
||||
protected secret(): void {}
|
||||
}
|
||||
class MessageWrapper {
|
||||
message: Message = new Message();
|
||||
wrap<T>() {
|
||||
let m = this.message;
|
||||
let f = function(this: T) {
|
||||
m.secret(); // should error
|
||||
~~~~~~
|
||||
!!! error TS2445: Property 'secret' is protected and only accessible within class 'Message' and its subclasses.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class A {
|
||||
protected a() {}
|
||||
}
|
||||
class B extends A {
|
||||
protected b() {}
|
||||
}
|
||||
class C extends A {
|
||||
protected c() {}
|
||||
}
|
||||
class Z {
|
||||
protected z() {}
|
||||
}
|
||||
|
||||
function bA<T extends A>(this: T, arg: B) {
|
||||
this.a();
|
||||
arg.a();
|
||||
arg.b(); // should error to avoid cross-hierarchy protected access https://www.typescriptlang.org/docs/handbook/2/classes.html#cross-hierarchy-protected-access
|
||||
~
|
||||
!!! error TS2445: Property 'b' is protected and only accessible within class 'B' and its subclasses.
|
||||
}
|
||||
function bB<T extends B>(this: T, arg: B) {
|
||||
this.a();
|
||||
this.b();
|
||||
arg.a();
|
||||
arg.b();
|
||||
}
|
||||
function bC<T extends C>(this: T, arg: B) {
|
||||
this.a();
|
||||
this.c();
|
||||
arg.a(); // should error
|
||||
~
|
||||
!!! error TS2446: Property 'a' is protected and only accessible through an instance of class 'C'. This is an instance of class 'B'.
|
||||
arg.b(); // should error
|
||||
~
|
||||
!!! error TS2445: Property 'b' is protected and only accessible within class 'B' and its subclasses.
|
||||
}
|
||||
function bZ<T extends Z>(this: T, arg: B) {
|
||||
this.z();
|
||||
arg.a(); // should error
|
||||
~
|
||||
!!! error TS2445: Property 'a' is protected and only accessible within class 'A' and its subclasses.
|
||||
arg.b(); // should error
|
||||
~
|
||||
!!! error TS2445: Property 'b' is protected and only accessible within class 'B' and its subclasses.
|
||||
}
|
||||
function bString<T extends string>(this: T, arg: B) {
|
||||
this.toLowerCase();
|
||||
arg.a(); // should error
|
||||
~
|
||||
!!! error TS2445: Property 'a' is protected and only accessible within class 'A' and its subclasses.
|
||||
arg.b(); // should error
|
||||
~
|
||||
!!! error TS2445: Property 'b' is protected and only accessible within class 'B' and its subclasses.
|
||||
}
|
||||
function bAny<T>(this: T, arg: B) {
|
||||
arg.a(); // should error
|
||||
~
|
||||
!!! error TS2445: Property 'a' is protected and only accessible within class 'A' and its subclasses.
|
||||
arg.b(); // should error
|
||||
~
|
||||
!!! error TS2445: Property 'b' is protected and only accessible within class 'B' and its subclasses.
|
||||
}
|
||||
|
||||
class D {
|
||||
protected d() {}
|
||||
|
||||
derived1(arg: D1) {
|
||||
arg.d();
|
||||
arg.d1(); // should error
|
||||
~~
|
||||
!!! error TS2445: Property 'd1' is protected and only accessible within class 'D1' and its subclasses.
|
||||
}
|
||||
derived1ThisD(this: D, arg: D1) {
|
||||
arg.d();
|
||||
arg.d1(); // should error
|
||||
~~
|
||||
!!! error TS2445: Property 'd1' is protected and only accessible within class 'D1' and its subclasses.
|
||||
}
|
||||
derived1ThisD1(this: D1, arg: D1) {
|
||||
arg.d();
|
||||
arg.d1();
|
||||
}
|
||||
|
||||
derived2(arg: D2) {
|
||||
arg.d(); // should error because of overridden method in D2
|
||||
~
|
||||
!!! error TS2445: Property 'd' is protected and only accessible within class 'D2' and its subclasses.
|
||||
arg.d2(); // should error
|
||||
~~
|
||||
!!! error TS2445: Property 'd2' is protected and only accessible within class 'D2' and its subclasses.
|
||||
}
|
||||
derived2ThisD(this: D, arg: D2) {
|
||||
arg.d(); // should error because of overridden method in D2
|
||||
~
|
||||
!!! error TS2445: Property 'd' is protected and only accessible within class 'D2' and its subclasses.
|
||||
arg.d2(); // should error
|
||||
~~
|
||||
!!! error TS2445: Property 'd2' is protected and only accessible within class 'D2' and its subclasses.
|
||||
}
|
||||
derived2ThisD2(this: D2, arg: D2) {
|
||||
arg.d();
|
||||
arg.d2();
|
||||
}
|
||||
}
|
||||
class D1 extends D {
|
||||
protected d1() {}
|
||||
}
|
||||
class D2 extends D {
|
||||
protected d() {}
|
||||
protected d2() {}
|
||||
}
|
||||
|
||||
|
||||
238
tests/baselines/reference/protectedMembersThisParameter.js
Normal file
238
tests/baselines/reference/protectedMembersThisParameter.js
Normal file
@ -0,0 +1,238 @@
|
||||
//// [protectedMembersThisParameter.ts]
|
||||
class Message {
|
||||
protected secret(): void {}
|
||||
}
|
||||
class MessageWrapper {
|
||||
message: Message = new Message();
|
||||
wrap<T>() {
|
||||
let m = this.message;
|
||||
let f = function(this: T) {
|
||||
m.secret(); // should error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class A {
|
||||
protected a() {}
|
||||
}
|
||||
class B extends A {
|
||||
protected b() {}
|
||||
}
|
||||
class C extends A {
|
||||
protected c() {}
|
||||
}
|
||||
class Z {
|
||||
protected z() {}
|
||||
}
|
||||
|
||||
function bA<T extends A>(this: T, arg: B) {
|
||||
this.a();
|
||||
arg.a();
|
||||
arg.b(); // should error to avoid cross-hierarchy protected access https://www.typescriptlang.org/docs/handbook/2/classes.html#cross-hierarchy-protected-access
|
||||
}
|
||||
function bB<T extends B>(this: T, arg: B) {
|
||||
this.a();
|
||||
this.b();
|
||||
arg.a();
|
||||
arg.b();
|
||||
}
|
||||
function bC<T extends C>(this: T, arg: B) {
|
||||
this.a();
|
||||
this.c();
|
||||
arg.a(); // should error
|
||||
arg.b(); // should error
|
||||
}
|
||||
function bZ<T extends Z>(this: T, arg: B) {
|
||||
this.z();
|
||||
arg.a(); // should error
|
||||
arg.b(); // should error
|
||||
}
|
||||
function bString<T extends string>(this: T, arg: B) {
|
||||
this.toLowerCase();
|
||||
arg.a(); // should error
|
||||
arg.b(); // should error
|
||||
}
|
||||
function bAny<T>(this: T, arg: B) {
|
||||
arg.a(); // should error
|
||||
arg.b(); // should error
|
||||
}
|
||||
|
||||
class D {
|
||||
protected d() {}
|
||||
|
||||
derived1(arg: D1) {
|
||||
arg.d();
|
||||
arg.d1(); // should error
|
||||
}
|
||||
derived1ThisD(this: D, arg: D1) {
|
||||
arg.d();
|
||||
arg.d1(); // should error
|
||||
}
|
||||
derived1ThisD1(this: D1, arg: D1) {
|
||||
arg.d();
|
||||
arg.d1();
|
||||
}
|
||||
|
||||
derived2(arg: D2) {
|
||||
arg.d(); // should error because of overridden method in D2
|
||||
arg.d2(); // should error
|
||||
}
|
||||
derived2ThisD(this: D, arg: D2) {
|
||||
arg.d(); // should error because of overridden method in D2
|
||||
arg.d2(); // should error
|
||||
}
|
||||
derived2ThisD2(this: D2, arg: D2) {
|
||||
arg.d();
|
||||
arg.d2();
|
||||
}
|
||||
}
|
||||
class D1 extends D {
|
||||
protected d1() {}
|
||||
}
|
||||
class D2 extends D {
|
||||
protected d() {}
|
||||
protected d2() {}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//// [protectedMembersThisParameter.js]
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
if (typeof b !== "function" && b !== null)
|
||||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
var Message = /** @class */ (function () {
|
||||
function Message() {
|
||||
}
|
||||
Message.prototype.secret = function () { };
|
||||
return Message;
|
||||
}());
|
||||
var MessageWrapper = /** @class */ (function () {
|
||||
function MessageWrapper() {
|
||||
this.message = new Message();
|
||||
}
|
||||
MessageWrapper.prototype.wrap = function () {
|
||||
var m = this.message;
|
||||
var f = function () {
|
||||
m.secret(); // should error
|
||||
};
|
||||
};
|
||||
return MessageWrapper;
|
||||
}());
|
||||
var A = /** @class */ (function () {
|
||||
function A() {
|
||||
}
|
||||
A.prototype.a = function () { };
|
||||
return A;
|
||||
}());
|
||||
var B = /** @class */ (function (_super) {
|
||||
__extends(B, _super);
|
||||
function B() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
B.prototype.b = function () { };
|
||||
return B;
|
||||
}(A));
|
||||
var C = /** @class */ (function (_super) {
|
||||
__extends(C, _super);
|
||||
function C() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
C.prototype.c = function () { };
|
||||
return C;
|
||||
}(A));
|
||||
var Z = /** @class */ (function () {
|
||||
function Z() {
|
||||
}
|
||||
Z.prototype.z = function () { };
|
||||
return Z;
|
||||
}());
|
||||
function bA(arg) {
|
||||
this.a();
|
||||
arg.a();
|
||||
arg.b(); // should error to avoid cross-hierarchy protected access https://www.typescriptlang.org/docs/handbook/2/classes.html#cross-hierarchy-protected-access
|
||||
}
|
||||
function bB(arg) {
|
||||
this.a();
|
||||
this.b();
|
||||
arg.a();
|
||||
arg.b();
|
||||
}
|
||||
function bC(arg) {
|
||||
this.a();
|
||||
this.c();
|
||||
arg.a(); // should error
|
||||
arg.b(); // should error
|
||||
}
|
||||
function bZ(arg) {
|
||||
this.z();
|
||||
arg.a(); // should error
|
||||
arg.b(); // should error
|
||||
}
|
||||
function bString(arg) {
|
||||
this.toLowerCase();
|
||||
arg.a(); // should error
|
||||
arg.b(); // should error
|
||||
}
|
||||
function bAny(arg) {
|
||||
arg.a(); // should error
|
||||
arg.b(); // should error
|
||||
}
|
||||
var D = /** @class */ (function () {
|
||||
function D() {
|
||||
}
|
||||
D.prototype.d = function () { };
|
||||
D.prototype.derived1 = function (arg) {
|
||||
arg.d();
|
||||
arg.d1(); // should error
|
||||
};
|
||||
D.prototype.derived1ThisD = function (arg) {
|
||||
arg.d();
|
||||
arg.d1(); // should error
|
||||
};
|
||||
D.prototype.derived1ThisD1 = function (arg) {
|
||||
arg.d();
|
||||
arg.d1();
|
||||
};
|
||||
D.prototype.derived2 = function (arg) {
|
||||
arg.d(); // should error because of overridden method in D2
|
||||
arg.d2(); // should error
|
||||
};
|
||||
D.prototype.derived2ThisD = function (arg) {
|
||||
arg.d(); // should error because of overridden method in D2
|
||||
arg.d2(); // should error
|
||||
};
|
||||
D.prototype.derived2ThisD2 = function (arg) {
|
||||
arg.d();
|
||||
arg.d2();
|
||||
};
|
||||
return D;
|
||||
}());
|
||||
var D1 = /** @class */ (function (_super) {
|
||||
__extends(D1, _super);
|
||||
function D1() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
D1.prototype.d1 = function () { };
|
||||
return D1;
|
||||
}(D));
|
||||
var D2 = /** @class */ (function (_super) {
|
||||
__extends(D2, _super);
|
||||
function D2() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
D2.prototype.d = function () { };
|
||||
D2.prototype.d2 = function () { };
|
||||
return D2;
|
||||
}(D));
|
||||
338
tests/baselines/reference/protectedMembersThisParameter.symbols
Normal file
338
tests/baselines/reference/protectedMembersThisParameter.symbols
Normal file
@ -0,0 +1,338 @@
|
||||
=== tests/cases/compiler/protectedMembersThisParameter.ts ===
|
||||
class Message {
|
||||
>Message : Symbol(Message, Decl(protectedMembersThisParameter.ts, 0, 0))
|
||||
|
||||
protected secret(): void {}
|
||||
>secret : Symbol(Message.secret, Decl(protectedMembersThisParameter.ts, 0, 15))
|
||||
}
|
||||
class MessageWrapper {
|
||||
>MessageWrapper : Symbol(MessageWrapper, Decl(protectedMembersThisParameter.ts, 2, 1))
|
||||
|
||||
message: Message = new Message();
|
||||
>message : Symbol(MessageWrapper.message, Decl(protectedMembersThisParameter.ts, 3, 22))
|
||||
>Message : Symbol(Message, Decl(protectedMembersThisParameter.ts, 0, 0))
|
||||
>Message : Symbol(Message, Decl(protectedMembersThisParameter.ts, 0, 0))
|
||||
|
||||
wrap<T>() {
|
||||
>wrap : Symbol(MessageWrapper.wrap, Decl(protectedMembersThisParameter.ts, 4, 35))
|
||||
>T : Symbol(T, Decl(protectedMembersThisParameter.ts, 5, 7))
|
||||
|
||||
let m = this.message;
|
||||
>m : Symbol(m, Decl(protectedMembersThisParameter.ts, 6, 7))
|
||||
>this.message : Symbol(MessageWrapper.message, Decl(protectedMembersThisParameter.ts, 3, 22))
|
||||
>this : Symbol(MessageWrapper, Decl(protectedMembersThisParameter.ts, 2, 1))
|
||||
>message : Symbol(MessageWrapper.message, Decl(protectedMembersThisParameter.ts, 3, 22))
|
||||
|
||||
let f = function(this: T) {
|
||||
>f : Symbol(f, Decl(protectedMembersThisParameter.ts, 7, 7))
|
||||
>this : Symbol(this, Decl(protectedMembersThisParameter.ts, 7, 21))
|
||||
>T : Symbol(T, Decl(protectedMembersThisParameter.ts, 5, 7))
|
||||
|
||||
m.secret(); // should error
|
||||
>m.secret : Symbol(Message.secret, Decl(protectedMembersThisParameter.ts, 0, 15))
|
||||
>m : Symbol(m, Decl(protectedMembersThisParameter.ts, 6, 7))
|
||||
>secret : Symbol(Message.secret, Decl(protectedMembersThisParameter.ts, 0, 15))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class A {
|
||||
>A : Symbol(A, Decl(protectedMembersThisParameter.ts, 11, 1))
|
||||
|
||||
protected a() {}
|
||||
>a : Symbol(A.a, Decl(protectedMembersThisParameter.ts, 13, 9))
|
||||
}
|
||||
class B extends A {
|
||||
>B : Symbol(B, Decl(protectedMembersThisParameter.ts, 15, 1))
|
||||
>A : Symbol(A, Decl(protectedMembersThisParameter.ts, 11, 1))
|
||||
|
||||
protected b() {}
|
||||
>b : Symbol(B.b, Decl(protectedMembersThisParameter.ts, 16, 19))
|
||||
}
|
||||
class C extends A {
|
||||
>C : Symbol(C, Decl(protectedMembersThisParameter.ts, 18, 1))
|
||||
>A : Symbol(A, Decl(protectedMembersThisParameter.ts, 11, 1))
|
||||
|
||||
protected c() {}
|
||||
>c : Symbol(C.c, Decl(protectedMembersThisParameter.ts, 19, 19))
|
||||
}
|
||||
class Z {
|
||||
>Z : Symbol(Z, Decl(protectedMembersThisParameter.ts, 21, 1))
|
||||
|
||||
protected z() {}
|
||||
>z : Symbol(Z.z, Decl(protectedMembersThisParameter.ts, 22, 9))
|
||||
}
|
||||
|
||||
function bA<T extends A>(this: T, arg: B) {
|
||||
>bA : Symbol(bA, Decl(protectedMembersThisParameter.ts, 24, 1))
|
||||
>T : Symbol(T, Decl(protectedMembersThisParameter.ts, 26, 12))
|
||||
>A : Symbol(A, Decl(protectedMembersThisParameter.ts, 11, 1))
|
||||
>this : Symbol(this, Decl(protectedMembersThisParameter.ts, 26, 25))
|
||||
>T : Symbol(T, Decl(protectedMembersThisParameter.ts, 26, 12))
|
||||
>arg : Symbol(arg, Decl(protectedMembersThisParameter.ts, 26, 33))
|
||||
>B : Symbol(B, Decl(protectedMembersThisParameter.ts, 15, 1))
|
||||
|
||||
this.a();
|
||||
>this.a : Symbol(A.a, Decl(protectedMembersThisParameter.ts, 13, 9))
|
||||
>this : Symbol(this, Decl(protectedMembersThisParameter.ts, 26, 25))
|
||||
>a : Symbol(A.a, Decl(protectedMembersThisParameter.ts, 13, 9))
|
||||
|
||||
arg.a();
|
||||
>arg.a : Symbol(A.a, Decl(protectedMembersThisParameter.ts, 13, 9))
|
||||
>arg : Symbol(arg, Decl(protectedMembersThisParameter.ts, 26, 33))
|
||||
>a : Symbol(A.a, Decl(protectedMembersThisParameter.ts, 13, 9))
|
||||
|
||||
arg.b(); // should error to avoid cross-hierarchy protected access https://www.typescriptlang.org/docs/handbook/2/classes.html#cross-hierarchy-protected-access
|
||||
>arg.b : Symbol(B.b, Decl(protectedMembersThisParameter.ts, 16, 19))
|
||||
>arg : Symbol(arg, Decl(protectedMembersThisParameter.ts, 26, 33))
|
||||
>b : Symbol(B.b, Decl(protectedMembersThisParameter.ts, 16, 19))
|
||||
}
|
||||
function bB<T extends B>(this: T, arg: B) {
|
||||
>bB : Symbol(bB, Decl(protectedMembersThisParameter.ts, 30, 1))
|
||||
>T : Symbol(T, Decl(protectedMembersThisParameter.ts, 31, 12))
|
||||
>B : Symbol(B, Decl(protectedMembersThisParameter.ts, 15, 1))
|
||||
>this : Symbol(this, Decl(protectedMembersThisParameter.ts, 31, 25))
|
||||
>T : Symbol(T, Decl(protectedMembersThisParameter.ts, 31, 12))
|
||||
>arg : Symbol(arg, Decl(protectedMembersThisParameter.ts, 31, 33))
|
||||
>B : Symbol(B, Decl(protectedMembersThisParameter.ts, 15, 1))
|
||||
|
||||
this.a();
|
||||
>this.a : Symbol(A.a, Decl(protectedMembersThisParameter.ts, 13, 9))
|
||||
>this : Symbol(this, Decl(protectedMembersThisParameter.ts, 31, 25))
|
||||
>a : Symbol(A.a, Decl(protectedMembersThisParameter.ts, 13, 9))
|
||||
|
||||
this.b();
|
||||
>this.b : Symbol(B.b, Decl(protectedMembersThisParameter.ts, 16, 19))
|
||||
>this : Symbol(this, Decl(protectedMembersThisParameter.ts, 31, 25))
|
||||
>b : Symbol(B.b, Decl(protectedMembersThisParameter.ts, 16, 19))
|
||||
|
||||
arg.a();
|
||||
>arg.a : Symbol(A.a, Decl(protectedMembersThisParameter.ts, 13, 9))
|
||||
>arg : Symbol(arg, Decl(protectedMembersThisParameter.ts, 31, 33))
|
||||
>a : Symbol(A.a, Decl(protectedMembersThisParameter.ts, 13, 9))
|
||||
|
||||
arg.b();
|
||||
>arg.b : Symbol(B.b, Decl(protectedMembersThisParameter.ts, 16, 19))
|
||||
>arg : Symbol(arg, Decl(protectedMembersThisParameter.ts, 31, 33))
|
||||
>b : Symbol(B.b, Decl(protectedMembersThisParameter.ts, 16, 19))
|
||||
}
|
||||
function bC<T extends C>(this: T, arg: B) {
|
||||
>bC : Symbol(bC, Decl(protectedMembersThisParameter.ts, 36, 1))
|
||||
>T : Symbol(T, Decl(protectedMembersThisParameter.ts, 37, 12))
|
||||
>C : Symbol(C, Decl(protectedMembersThisParameter.ts, 18, 1))
|
||||
>this : Symbol(this, Decl(protectedMembersThisParameter.ts, 37, 25))
|
||||
>T : Symbol(T, Decl(protectedMembersThisParameter.ts, 37, 12))
|
||||
>arg : Symbol(arg, Decl(protectedMembersThisParameter.ts, 37, 33))
|
||||
>B : Symbol(B, Decl(protectedMembersThisParameter.ts, 15, 1))
|
||||
|
||||
this.a();
|
||||
>this.a : Symbol(A.a, Decl(protectedMembersThisParameter.ts, 13, 9))
|
||||
>this : Symbol(this, Decl(protectedMembersThisParameter.ts, 37, 25))
|
||||
>a : Symbol(A.a, Decl(protectedMembersThisParameter.ts, 13, 9))
|
||||
|
||||
this.c();
|
||||
>this.c : Symbol(C.c, Decl(protectedMembersThisParameter.ts, 19, 19))
|
||||
>this : Symbol(this, Decl(protectedMembersThisParameter.ts, 37, 25))
|
||||
>c : Symbol(C.c, Decl(protectedMembersThisParameter.ts, 19, 19))
|
||||
|
||||
arg.a(); // should error
|
||||
>arg.a : Symbol(A.a, Decl(protectedMembersThisParameter.ts, 13, 9))
|
||||
>arg : Symbol(arg, Decl(protectedMembersThisParameter.ts, 37, 33))
|
||||
>a : Symbol(A.a, Decl(protectedMembersThisParameter.ts, 13, 9))
|
||||
|
||||
arg.b(); // should error
|
||||
>arg.b : Symbol(B.b, Decl(protectedMembersThisParameter.ts, 16, 19))
|
||||
>arg : Symbol(arg, Decl(protectedMembersThisParameter.ts, 37, 33))
|
||||
>b : Symbol(B.b, Decl(protectedMembersThisParameter.ts, 16, 19))
|
||||
}
|
||||
function bZ<T extends Z>(this: T, arg: B) {
|
||||
>bZ : Symbol(bZ, Decl(protectedMembersThisParameter.ts, 42, 1))
|
||||
>T : Symbol(T, Decl(protectedMembersThisParameter.ts, 43, 12))
|
||||
>Z : Symbol(Z, Decl(protectedMembersThisParameter.ts, 21, 1))
|
||||
>this : Symbol(this, Decl(protectedMembersThisParameter.ts, 43, 25))
|
||||
>T : Symbol(T, Decl(protectedMembersThisParameter.ts, 43, 12))
|
||||
>arg : Symbol(arg, Decl(protectedMembersThisParameter.ts, 43, 33))
|
||||
>B : Symbol(B, Decl(protectedMembersThisParameter.ts, 15, 1))
|
||||
|
||||
this.z();
|
||||
>this.z : Symbol(Z.z, Decl(protectedMembersThisParameter.ts, 22, 9))
|
||||
>this : Symbol(this, Decl(protectedMembersThisParameter.ts, 43, 25))
|
||||
>z : Symbol(Z.z, Decl(protectedMembersThisParameter.ts, 22, 9))
|
||||
|
||||
arg.a(); // should error
|
||||
>arg.a : Symbol(A.a, Decl(protectedMembersThisParameter.ts, 13, 9))
|
||||
>arg : Symbol(arg, Decl(protectedMembersThisParameter.ts, 43, 33))
|
||||
>a : Symbol(A.a, Decl(protectedMembersThisParameter.ts, 13, 9))
|
||||
|
||||
arg.b(); // should error
|
||||
>arg.b : Symbol(B.b, Decl(protectedMembersThisParameter.ts, 16, 19))
|
||||
>arg : Symbol(arg, Decl(protectedMembersThisParameter.ts, 43, 33))
|
||||
>b : Symbol(B.b, Decl(protectedMembersThisParameter.ts, 16, 19))
|
||||
}
|
||||
function bString<T extends string>(this: T, arg: B) {
|
||||
>bString : Symbol(bString, Decl(protectedMembersThisParameter.ts, 47, 1))
|
||||
>T : Symbol(T, Decl(protectedMembersThisParameter.ts, 48, 17))
|
||||
>this : Symbol(this, Decl(protectedMembersThisParameter.ts, 48, 35))
|
||||
>T : Symbol(T, Decl(protectedMembersThisParameter.ts, 48, 17))
|
||||
>arg : Symbol(arg, Decl(protectedMembersThisParameter.ts, 48, 43))
|
||||
>B : Symbol(B, Decl(protectedMembersThisParameter.ts, 15, 1))
|
||||
|
||||
this.toLowerCase();
|
||||
>this.toLowerCase : Symbol(String.toLowerCase, Decl(lib.es5.d.ts, --, --))
|
||||
>this : Symbol(this, Decl(protectedMembersThisParameter.ts, 48, 35))
|
||||
>toLowerCase : Symbol(String.toLowerCase, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
arg.a(); // should error
|
||||
>arg.a : Symbol(A.a, Decl(protectedMembersThisParameter.ts, 13, 9))
|
||||
>arg : Symbol(arg, Decl(protectedMembersThisParameter.ts, 48, 43))
|
||||
>a : Symbol(A.a, Decl(protectedMembersThisParameter.ts, 13, 9))
|
||||
|
||||
arg.b(); // should error
|
||||
>arg.b : Symbol(B.b, Decl(protectedMembersThisParameter.ts, 16, 19))
|
||||
>arg : Symbol(arg, Decl(protectedMembersThisParameter.ts, 48, 43))
|
||||
>b : Symbol(B.b, Decl(protectedMembersThisParameter.ts, 16, 19))
|
||||
}
|
||||
function bAny<T>(this: T, arg: B) {
|
||||
>bAny : Symbol(bAny, Decl(protectedMembersThisParameter.ts, 52, 1))
|
||||
>T : Symbol(T, Decl(protectedMembersThisParameter.ts, 53, 14))
|
||||
>this : Symbol(this, Decl(protectedMembersThisParameter.ts, 53, 17))
|
||||
>T : Symbol(T, Decl(protectedMembersThisParameter.ts, 53, 14))
|
||||
>arg : Symbol(arg, Decl(protectedMembersThisParameter.ts, 53, 25))
|
||||
>B : Symbol(B, Decl(protectedMembersThisParameter.ts, 15, 1))
|
||||
|
||||
arg.a(); // should error
|
||||
>arg.a : Symbol(A.a, Decl(protectedMembersThisParameter.ts, 13, 9))
|
||||
>arg : Symbol(arg, Decl(protectedMembersThisParameter.ts, 53, 25))
|
||||
>a : Symbol(A.a, Decl(protectedMembersThisParameter.ts, 13, 9))
|
||||
|
||||
arg.b(); // should error
|
||||
>arg.b : Symbol(B.b, Decl(protectedMembersThisParameter.ts, 16, 19))
|
||||
>arg : Symbol(arg, Decl(protectedMembersThisParameter.ts, 53, 25))
|
||||
>b : Symbol(B.b, Decl(protectedMembersThisParameter.ts, 16, 19))
|
||||
}
|
||||
|
||||
class D {
|
||||
>D : Symbol(D, Decl(protectedMembersThisParameter.ts, 56, 1))
|
||||
|
||||
protected d() {}
|
||||
>d : Symbol(D.d, Decl(protectedMembersThisParameter.ts, 58, 9))
|
||||
|
||||
derived1(arg: D1) {
|
||||
>derived1 : Symbol(D.derived1, Decl(protectedMembersThisParameter.ts, 59, 18))
|
||||
>arg : Symbol(arg, Decl(protectedMembersThisParameter.ts, 61, 11))
|
||||
>D1 : Symbol(D1, Decl(protectedMembersThisParameter.ts, 86, 1))
|
||||
|
||||
arg.d();
|
||||
>arg.d : Symbol(D.d, Decl(protectedMembersThisParameter.ts, 58, 9))
|
||||
>arg : Symbol(arg, Decl(protectedMembersThisParameter.ts, 61, 11))
|
||||
>d : Symbol(D.d, Decl(protectedMembersThisParameter.ts, 58, 9))
|
||||
|
||||
arg.d1(); // should error
|
||||
>arg.d1 : Symbol(D1.d1, Decl(protectedMembersThisParameter.ts, 87, 20))
|
||||
>arg : Symbol(arg, Decl(protectedMembersThisParameter.ts, 61, 11))
|
||||
>d1 : Symbol(D1.d1, Decl(protectedMembersThisParameter.ts, 87, 20))
|
||||
}
|
||||
derived1ThisD(this: D, arg: D1) {
|
||||
>derived1ThisD : Symbol(D.derived1ThisD, Decl(protectedMembersThisParameter.ts, 64, 3))
|
||||
>this : Symbol(this, Decl(protectedMembersThisParameter.ts, 65, 16))
|
||||
>D : Symbol(D, Decl(protectedMembersThisParameter.ts, 56, 1))
|
||||
>arg : Symbol(arg, Decl(protectedMembersThisParameter.ts, 65, 24))
|
||||
>D1 : Symbol(D1, Decl(protectedMembersThisParameter.ts, 86, 1))
|
||||
|
||||
arg.d();
|
||||
>arg.d : Symbol(D.d, Decl(protectedMembersThisParameter.ts, 58, 9))
|
||||
>arg : Symbol(arg, Decl(protectedMembersThisParameter.ts, 65, 24))
|
||||
>d : Symbol(D.d, Decl(protectedMembersThisParameter.ts, 58, 9))
|
||||
|
||||
arg.d1(); // should error
|
||||
>arg.d1 : Symbol(D1.d1, Decl(protectedMembersThisParameter.ts, 87, 20))
|
||||
>arg : Symbol(arg, Decl(protectedMembersThisParameter.ts, 65, 24))
|
||||
>d1 : Symbol(D1.d1, Decl(protectedMembersThisParameter.ts, 87, 20))
|
||||
}
|
||||
derived1ThisD1(this: D1, arg: D1) {
|
||||
>derived1ThisD1 : Symbol(D.derived1ThisD1, Decl(protectedMembersThisParameter.ts, 68, 3))
|
||||
>this : Symbol(this, Decl(protectedMembersThisParameter.ts, 69, 17))
|
||||
>D1 : Symbol(D1, Decl(protectedMembersThisParameter.ts, 86, 1))
|
||||
>arg : Symbol(arg, Decl(protectedMembersThisParameter.ts, 69, 26))
|
||||
>D1 : Symbol(D1, Decl(protectedMembersThisParameter.ts, 86, 1))
|
||||
|
||||
arg.d();
|
||||
>arg.d : Symbol(D.d, Decl(protectedMembersThisParameter.ts, 58, 9))
|
||||
>arg : Symbol(arg, Decl(protectedMembersThisParameter.ts, 69, 26))
|
||||
>d : Symbol(D.d, Decl(protectedMembersThisParameter.ts, 58, 9))
|
||||
|
||||
arg.d1();
|
||||
>arg.d1 : Symbol(D1.d1, Decl(protectedMembersThisParameter.ts, 87, 20))
|
||||
>arg : Symbol(arg, Decl(protectedMembersThisParameter.ts, 69, 26))
|
||||
>d1 : Symbol(D1.d1, Decl(protectedMembersThisParameter.ts, 87, 20))
|
||||
}
|
||||
|
||||
derived2(arg: D2) {
|
||||
>derived2 : Symbol(D.derived2, Decl(protectedMembersThisParameter.ts, 72, 3))
|
||||
>arg : Symbol(arg, Decl(protectedMembersThisParameter.ts, 74, 11))
|
||||
>D2 : Symbol(D2, Decl(protectedMembersThisParameter.ts, 89, 1))
|
||||
|
||||
arg.d(); // should error because of overridden method in D2
|
||||
>arg.d : Symbol(D2.d, Decl(protectedMembersThisParameter.ts, 90, 20))
|
||||
>arg : Symbol(arg, Decl(protectedMembersThisParameter.ts, 74, 11))
|
||||
>d : Symbol(D2.d, Decl(protectedMembersThisParameter.ts, 90, 20))
|
||||
|
||||
arg.d2(); // should error
|
||||
>arg.d2 : Symbol(D2.d2, Decl(protectedMembersThisParameter.ts, 91, 18))
|
||||
>arg : Symbol(arg, Decl(protectedMembersThisParameter.ts, 74, 11))
|
||||
>d2 : Symbol(D2.d2, Decl(protectedMembersThisParameter.ts, 91, 18))
|
||||
}
|
||||
derived2ThisD(this: D, arg: D2) {
|
||||
>derived2ThisD : Symbol(D.derived2ThisD, Decl(protectedMembersThisParameter.ts, 77, 3))
|
||||
>this : Symbol(this, Decl(protectedMembersThisParameter.ts, 78, 16))
|
||||
>D : Symbol(D, Decl(protectedMembersThisParameter.ts, 56, 1))
|
||||
>arg : Symbol(arg, Decl(protectedMembersThisParameter.ts, 78, 24))
|
||||
>D2 : Symbol(D2, Decl(protectedMembersThisParameter.ts, 89, 1))
|
||||
|
||||
arg.d(); // should error because of overridden method in D2
|
||||
>arg.d : Symbol(D2.d, Decl(protectedMembersThisParameter.ts, 90, 20))
|
||||
>arg : Symbol(arg, Decl(protectedMembersThisParameter.ts, 78, 24))
|
||||
>d : Symbol(D2.d, Decl(protectedMembersThisParameter.ts, 90, 20))
|
||||
|
||||
arg.d2(); // should error
|
||||
>arg.d2 : Symbol(D2.d2, Decl(protectedMembersThisParameter.ts, 91, 18))
|
||||
>arg : Symbol(arg, Decl(protectedMembersThisParameter.ts, 78, 24))
|
||||
>d2 : Symbol(D2.d2, Decl(protectedMembersThisParameter.ts, 91, 18))
|
||||
}
|
||||
derived2ThisD2(this: D2, arg: D2) {
|
||||
>derived2ThisD2 : Symbol(D.derived2ThisD2, Decl(protectedMembersThisParameter.ts, 81, 3))
|
||||
>this : Symbol(this, Decl(protectedMembersThisParameter.ts, 82, 17))
|
||||
>D2 : Symbol(D2, Decl(protectedMembersThisParameter.ts, 89, 1))
|
||||
>arg : Symbol(arg, Decl(protectedMembersThisParameter.ts, 82, 26))
|
||||
>D2 : Symbol(D2, Decl(protectedMembersThisParameter.ts, 89, 1))
|
||||
|
||||
arg.d();
|
||||
>arg.d : Symbol(D2.d, Decl(protectedMembersThisParameter.ts, 90, 20))
|
||||
>arg : Symbol(arg, Decl(protectedMembersThisParameter.ts, 82, 26))
|
||||
>d : Symbol(D2.d, Decl(protectedMembersThisParameter.ts, 90, 20))
|
||||
|
||||
arg.d2();
|
||||
>arg.d2 : Symbol(D2.d2, Decl(protectedMembersThisParameter.ts, 91, 18))
|
||||
>arg : Symbol(arg, Decl(protectedMembersThisParameter.ts, 82, 26))
|
||||
>d2 : Symbol(D2.d2, Decl(protectedMembersThisParameter.ts, 91, 18))
|
||||
}
|
||||
}
|
||||
class D1 extends D {
|
||||
>D1 : Symbol(D1, Decl(protectedMembersThisParameter.ts, 86, 1))
|
||||
>D : Symbol(D, Decl(protectedMembersThisParameter.ts, 56, 1))
|
||||
|
||||
protected d1() {}
|
||||
>d1 : Symbol(D1.d1, Decl(protectedMembersThisParameter.ts, 87, 20))
|
||||
}
|
||||
class D2 extends D {
|
||||
>D2 : Symbol(D2, Decl(protectedMembersThisParameter.ts, 89, 1))
|
||||
>D : Symbol(D, Decl(protectedMembersThisParameter.ts, 56, 1))
|
||||
|
||||
protected d() {}
|
||||
>d : Symbol(D2.d, Decl(protectedMembersThisParameter.ts, 90, 20))
|
||||
|
||||
protected d2() {}
|
||||
>d2 : Symbol(D2.d2, Decl(protectedMembersThisParameter.ts, 91, 18))
|
||||
}
|
||||
|
||||
|
||||
337
tests/baselines/reference/protectedMembersThisParameter.types
Normal file
337
tests/baselines/reference/protectedMembersThisParameter.types
Normal file
@ -0,0 +1,337 @@
|
||||
=== tests/cases/compiler/protectedMembersThisParameter.ts ===
|
||||
class Message {
|
||||
>Message : Message
|
||||
|
||||
protected secret(): void {}
|
||||
>secret : () => void
|
||||
}
|
||||
class MessageWrapper {
|
||||
>MessageWrapper : MessageWrapper
|
||||
|
||||
message: Message = new Message();
|
||||
>message : Message
|
||||
>new Message() : Message
|
||||
>Message : typeof Message
|
||||
|
||||
wrap<T>() {
|
||||
>wrap : <T>() => void
|
||||
|
||||
let m = this.message;
|
||||
>m : Message
|
||||
>this.message : Message
|
||||
>this : this
|
||||
>message : Message
|
||||
|
||||
let f = function(this: T) {
|
||||
>f : (this: T) => void
|
||||
>function(this: T) { m.secret(); // should error } : (this: T) => void
|
||||
>this : T
|
||||
|
||||
m.secret(); // should error
|
||||
>m.secret() : void
|
||||
>m.secret : () => void
|
||||
>m : Message
|
||||
>secret : () => void
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class A {
|
||||
>A : A
|
||||
|
||||
protected a() {}
|
||||
>a : () => void
|
||||
}
|
||||
class B extends A {
|
||||
>B : B
|
||||
>A : A
|
||||
|
||||
protected b() {}
|
||||
>b : () => void
|
||||
}
|
||||
class C extends A {
|
||||
>C : C
|
||||
>A : A
|
||||
|
||||
protected c() {}
|
||||
>c : () => void
|
||||
}
|
||||
class Z {
|
||||
>Z : Z
|
||||
|
||||
protected z() {}
|
||||
>z : () => void
|
||||
}
|
||||
|
||||
function bA<T extends A>(this: T, arg: B) {
|
||||
>bA : <T extends A>(this: T, arg: B) => void
|
||||
>this : T
|
||||
>arg : B
|
||||
|
||||
this.a();
|
||||
>this.a() : void
|
||||
>this.a : () => void
|
||||
>this : T
|
||||
>a : () => void
|
||||
|
||||
arg.a();
|
||||
>arg.a() : void
|
||||
>arg.a : () => void
|
||||
>arg : B
|
||||
>a : () => void
|
||||
|
||||
arg.b(); // should error to avoid cross-hierarchy protected access https://www.typescriptlang.org/docs/handbook/2/classes.html#cross-hierarchy-protected-access
|
||||
>arg.b() : void
|
||||
>arg.b : () => void
|
||||
>arg : B
|
||||
>b : () => void
|
||||
}
|
||||
function bB<T extends B>(this: T, arg: B) {
|
||||
>bB : <T extends B>(this: T, arg: B) => void
|
||||
>this : T
|
||||
>arg : B
|
||||
|
||||
this.a();
|
||||
>this.a() : void
|
||||
>this.a : () => void
|
||||
>this : T
|
||||
>a : () => void
|
||||
|
||||
this.b();
|
||||
>this.b() : void
|
||||
>this.b : () => void
|
||||
>this : T
|
||||
>b : () => void
|
||||
|
||||
arg.a();
|
||||
>arg.a() : void
|
||||
>arg.a : () => void
|
||||
>arg : B
|
||||
>a : () => void
|
||||
|
||||
arg.b();
|
||||
>arg.b() : void
|
||||
>arg.b : () => void
|
||||
>arg : B
|
||||
>b : () => void
|
||||
}
|
||||
function bC<T extends C>(this: T, arg: B) {
|
||||
>bC : <T extends C>(this: T, arg: B) => void
|
||||
>this : T
|
||||
>arg : B
|
||||
|
||||
this.a();
|
||||
>this.a() : void
|
||||
>this.a : () => void
|
||||
>this : T
|
||||
>a : () => void
|
||||
|
||||
this.c();
|
||||
>this.c() : void
|
||||
>this.c : () => void
|
||||
>this : T
|
||||
>c : () => void
|
||||
|
||||
arg.a(); // should error
|
||||
>arg.a() : void
|
||||
>arg.a : () => void
|
||||
>arg : B
|
||||
>a : () => void
|
||||
|
||||
arg.b(); // should error
|
||||
>arg.b() : void
|
||||
>arg.b : () => void
|
||||
>arg : B
|
||||
>b : () => void
|
||||
}
|
||||
function bZ<T extends Z>(this: T, arg: B) {
|
||||
>bZ : <T extends Z>(this: T, arg: B) => void
|
||||
>this : T
|
||||
>arg : B
|
||||
|
||||
this.z();
|
||||
>this.z() : void
|
||||
>this.z : () => void
|
||||
>this : T
|
||||
>z : () => void
|
||||
|
||||
arg.a(); // should error
|
||||
>arg.a() : void
|
||||
>arg.a : () => void
|
||||
>arg : B
|
||||
>a : () => void
|
||||
|
||||
arg.b(); // should error
|
||||
>arg.b() : void
|
||||
>arg.b : () => void
|
||||
>arg : B
|
||||
>b : () => void
|
||||
}
|
||||
function bString<T extends string>(this: T, arg: B) {
|
||||
>bString : <T extends string>(this: T, arg: B) => void
|
||||
>this : T
|
||||
>arg : B
|
||||
|
||||
this.toLowerCase();
|
||||
>this.toLowerCase() : string
|
||||
>this.toLowerCase : () => string
|
||||
>this : T
|
||||
>toLowerCase : () => string
|
||||
|
||||
arg.a(); // should error
|
||||
>arg.a() : void
|
||||
>arg.a : () => void
|
||||
>arg : B
|
||||
>a : () => void
|
||||
|
||||
arg.b(); // should error
|
||||
>arg.b() : void
|
||||
>arg.b : () => void
|
||||
>arg : B
|
||||
>b : () => void
|
||||
}
|
||||
function bAny<T>(this: T, arg: B) {
|
||||
>bAny : <T>(this: T, arg: B) => void
|
||||
>this : T
|
||||
>arg : B
|
||||
|
||||
arg.a(); // should error
|
||||
>arg.a() : void
|
||||
>arg.a : () => void
|
||||
>arg : B
|
||||
>a : () => void
|
||||
|
||||
arg.b(); // should error
|
||||
>arg.b() : void
|
||||
>arg.b : () => void
|
||||
>arg : B
|
||||
>b : () => void
|
||||
}
|
||||
|
||||
class D {
|
||||
>D : D
|
||||
|
||||
protected d() {}
|
||||
>d : () => void
|
||||
|
||||
derived1(arg: D1) {
|
||||
>derived1 : (arg: D1) => void
|
||||
>arg : D1
|
||||
|
||||
arg.d();
|
||||
>arg.d() : void
|
||||
>arg.d : () => void
|
||||
>arg : D1
|
||||
>d : () => void
|
||||
|
||||
arg.d1(); // should error
|
||||
>arg.d1() : void
|
||||
>arg.d1 : () => void
|
||||
>arg : D1
|
||||
>d1 : () => void
|
||||
}
|
||||
derived1ThisD(this: D, arg: D1) {
|
||||
>derived1ThisD : (this: D, arg: D1) => void
|
||||
>this : D
|
||||
>arg : D1
|
||||
|
||||
arg.d();
|
||||
>arg.d() : void
|
||||
>arg.d : () => void
|
||||
>arg : D1
|
||||
>d : () => void
|
||||
|
||||
arg.d1(); // should error
|
||||
>arg.d1() : void
|
||||
>arg.d1 : () => void
|
||||
>arg : D1
|
||||
>d1 : () => void
|
||||
}
|
||||
derived1ThisD1(this: D1, arg: D1) {
|
||||
>derived1ThisD1 : (this: D1, arg: D1) => void
|
||||
>this : D1
|
||||
>arg : D1
|
||||
|
||||
arg.d();
|
||||
>arg.d() : void
|
||||
>arg.d : () => void
|
||||
>arg : D1
|
||||
>d : () => void
|
||||
|
||||
arg.d1();
|
||||
>arg.d1() : void
|
||||
>arg.d1 : () => void
|
||||
>arg : D1
|
||||
>d1 : () => void
|
||||
}
|
||||
|
||||
derived2(arg: D2) {
|
||||
>derived2 : (arg: D2) => void
|
||||
>arg : D2
|
||||
|
||||
arg.d(); // should error because of overridden method in D2
|
||||
>arg.d() : void
|
||||
>arg.d : () => void
|
||||
>arg : D2
|
||||
>d : () => void
|
||||
|
||||
arg.d2(); // should error
|
||||
>arg.d2() : void
|
||||
>arg.d2 : () => void
|
||||
>arg : D2
|
||||
>d2 : () => void
|
||||
}
|
||||
derived2ThisD(this: D, arg: D2) {
|
||||
>derived2ThisD : (this: D, arg: D2) => void
|
||||
>this : D
|
||||
>arg : D2
|
||||
|
||||
arg.d(); // should error because of overridden method in D2
|
||||
>arg.d() : void
|
||||
>arg.d : () => void
|
||||
>arg : D2
|
||||
>d : () => void
|
||||
|
||||
arg.d2(); // should error
|
||||
>arg.d2() : void
|
||||
>arg.d2 : () => void
|
||||
>arg : D2
|
||||
>d2 : () => void
|
||||
}
|
||||
derived2ThisD2(this: D2, arg: D2) {
|
||||
>derived2ThisD2 : (this: D2, arg: D2) => void
|
||||
>this : D2
|
||||
>arg : D2
|
||||
|
||||
arg.d();
|
||||
>arg.d() : void
|
||||
>arg.d : () => void
|
||||
>arg : D2
|
||||
>d : () => void
|
||||
|
||||
arg.d2();
|
||||
>arg.d2() : void
|
||||
>arg.d2 : () => void
|
||||
>arg : D2
|
||||
>d2 : () => void
|
||||
}
|
||||
}
|
||||
class D1 extends D {
|
||||
>D1 : D1
|
||||
>D : D
|
||||
|
||||
protected d1() {}
|
||||
>d1 : () => void
|
||||
}
|
||||
class D2 extends D {
|
||||
>D2 : D2
|
||||
>D : D
|
||||
|
||||
protected d() {}
|
||||
>d : () => void
|
||||
|
||||
protected d2() {}
|
||||
>d2 : () => void
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
tests/cases/compiler/publicGetterProtectedSetterFromThisParameter.ts(33,7): error TS2446: Property 'q' is protected and only accessible through an instance of class 'A'. This is an instance of class 'B'.
|
||||
tests/cases/compiler/publicGetterProtectedSetterFromThisParameter.ts(34,7): error TS2446: Property 'u' is protected and only accessible through an instance of class 'A'. This is an instance of class 'B'.
|
||||
tests/cases/compiler/publicGetterProtectedSetterFromThisParameter.ts(33,7): error TS2445: Property 'q' is protected and only accessible within class 'B' and its subclasses.
|
||||
tests/cases/compiler/publicGetterProtectedSetterFromThisParameter.ts(34,7): error TS2445: Property 'u' is protected and only accessible within class 'B' and its subclasses.
|
||||
|
||||
|
||||
==== tests/cases/compiler/publicGetterProtectedSetterFromThisParameter.ts (2 errors) ====
|
||||
@ -37,9 +37,9 @@ tests/cases/compiler/publicGetterProtectedSetterFromThisParameter.ts(34,7): erro
|
||||
// These should error
|
||||
b.q = 0;
|
||||
~
|
||||
!!! error TS2446: Property 'q' is protected and only accessible through an instance of class 'A'. This is an instance of class 'B'.
|
||||
!!! error TS2445: Property 'q' is protected and only accessible within class 'B' and its subclasses.
|
||||
b.u = 0;
|
||||
~
|
||||
!!! error TS2446: Property 'u' is protected and only accessible through an instance of class 'A'. This is an instance of class 'B'.
|
||||
!!! error TS2445: Property 'u' is protected and only accessible within class 'B' and its subclasses.
|
||||
}
|
||||
|
||||
95
tests/cases/compiler/protectedMembersThisParameter.ts
Normal file
95
tests/cases/compiler/protectedMembersThisParameter.ts
Normal file
@ -0,0 +1,95 @@
|
||||
class Message {
|
||||
protected secret(): void {}
|
||||
}
|
||||
class MessageWrapper {
|
||||
message: Message = new Message();
|
||||
wrap<T>() {
|
||||
let m = this.message;
|
||||
let f = function(this: T) {
|
||||
m.secret(); // should error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class A {
|
||||
protected a() {}
|
||||
}
|
||||
class B extends A {
|
||||
protected b() {}
|
||||
}
|
||||
class C extends A {
|
||||
protected c() {}
|
||||
}
|
||||
class Z {
|
||||
protected z() {}
|
||||
}
|
||||
|
||||
function bA<T extends A>(this: T, arg: B) {
|
||||
this.a();
|
||||
arg.a();
|
||||
arg.b(); // should error to avoid cross-hierarchy protected access https://www.typescriptlang.org/docs/handbook/2/classes.html#cross-hierarchy-protected-access
|
||||
}
|
||||
function bB<T extends B>(this: T, arg: B) {
|
||||
this.a();
|
||||
this.b();
|
||||
arg.a();
|
||||
arg.b();
|
||||
}
|
||||
function bC<T extends C>(this: T, arg: B) {
|
||||
this.a();
|
||||
this.c();
|
||||
arg.a(); // should error
|
||||
arg.b(); // should error
|
||||
}
|
||||
function bZ<T extends Z>(this: T, arg: B) {
|
||||
this.z();
|
||||
arg.a(); // should error
|
||||
arg.b(); // should error
|
||||
}
|
||||
function bString<T extends string>(this: T, arg: B) {
|
||||
this.toLowerCase();
|
||||
arg.a(); // should error
|
||||
arg.b(); // should error
|
||||
}
|
||||
function bAny<T>(this: T, arg: B) {
|
||||
arg.a(); // should error
|
||||
arg.b(); // should error
|
||||
}
|
||||
|
||||
class D {
|
||||
protected d() {}
|
||||
|
||||
derived1(arg: D1) {
|
||||
arg.d();
|
||||
arg.d1(); // should error
|
||||
}
|
||||
derived1ThisD(this: D, arg: D1) {
|
||||
arg.d();
|
||||
arg.d1(); // should error
|
||||
}
|
||||
derived1ThisD1(this: D1, arg: D1) {
|
||||
arg.d();
|
||||
arg.d1();
|
||||
}
|
||||
|
||||
derived2(arg: D2) {
|
||||
arg.d(); // should error because of overridden method in D2
|
||||
arg.d2(); // should error
|
||||
}
|
||||
derived2ThisD(this: D, arg: D2) {
|
||||
arg.d(); // should error because of overridden method in D2
|
||||
arg.d2(); // should error
|
||||
}
|
||||
derived2ThisD2(this: D2, arg: D2) {
|
||||
arg.d();
|
||||
arg.d2();
|
||||
}
|
||||
}
|
||||
class D1 extends D {
|
||||
protected d1() {}
|
||||
}
|
||||
class D2 extends D {
|
||||
protected d() {}
|
||||
protected d2() {}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user