mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-06 02:33:53 -06:00
Error accessing abstract property in constructor of abstract subclass
Fixes: #26411
This commit is contained in:
parent
c62920ac81
commit
c203c27f00
@ -17986,7 +17986,7 @@ namespace ts {
|
||||
// Referencing abstract properties within their own constructors is not allowed
|
||||
if ((flags & ModifierFlags.Abstract) && isThisProperty(node) && symbolHasNonMethodDeclaration(prop)) {
|
||||
const declaringClassDeclaration = getClassLikeDeclarationOfSymbol(getParentOfSymbol(prop)!);
|
||||
if (declaringClassDeclaration && isNodeUsedDuringClassInitialization(node, declaringClassDeclaration)) {
|
||||
if (declaringClassDeclaration && isNodeUsedDuringClassInitialization(node)) {
|
||||
error(errorNode, Diagnostics.Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor, symbolToString(prop), getTextOfIdentifierOrLiteral(declaringClassDeclaration.name!)); // TODO: GH#18217
|
||||
return false;
|
||||
}
|
||||
@ -27120,12 +27120,12 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
function isNodeUsedDuringClassInitialization(node: Node, classDeclaration: ClassLikeDeclaration) {
|
||||
function isNodeUsedDuringClassInitialization(node: Node) {
|
||||
return !!findAncestor(node, element => {
|
||||
if ((isConstructorDeclaration(element) && nodeIsPresent(element.body) || isPropertyDeclaration(element)) && element.parent === classDeclaration) {
|
||||
if (isConstructorDeclaration(element) && nodeIsPresent(element.body) || isPropertyDeclaration(element)) {
|
||||
return true;
|
||||
}
|
||||
else if (element === classDeclaration || isFunctionLikeDeclaration(element)) {
|
||||
else if (isClassLike(element) || isFunctionLikeDeclaration(element)) {
|
||||
return "quit";
|
||||
}
|
||||
|
||||
|
||||
@ -2,9 +2,10 @@ tests/cases/compiler/abstractPropertyInConstructor.ts(4,24): error TS2715: Abstr
|
||||
tests/cases/compiler/abstractPropertyInConstructor.ts(7,18): error TS2715: Abstract property 'prop' in class 'AbstractClass' cannot be accessed in the constructor.
|
||||
tests/cases/compiler/abstractPropertyInConstructor.ts(9,14): error TS2715: Abstract property 'cb' in class 'AbstractClass' cannot be accessed in the constructor.
|
||||
tests/cases/compiler/abstractPropertyInConstructor.ts(25,18): error TS2715: Abstract property 'prop' in class 'AbstractClass' cannot be accessed in the constructor.
|
||||
tests/cases/compiler/abstractPropertyInConstructor.ts(39,22): error TS2715: Abstract property 'prop' in class 'AbstractClass' cannot be accessed in the constructor.
|
||||
|
||||
|
||||
==== tests/cases/compiler/abstractPropertyInConstructor.ts (4 errors) ====
|
||||
==== tests/cases/compiler/abstractPropertyInConstructor.ts (5 errors) ====
|
||||
abstract class AbstractClass {
|
||||
constructor(str: string, other: AbstractClass) {
|
||||
this.method(parseInt(str));
|
||||
@ -45,6 +46,38 @@ tests/cases/compiler/abstractPropertyInConstructor.ts(25,18): error TS2715: Abst
|
||||
}
|
||||
}
|
||||
|
||||
abstract class DerivedAbstractClass extends AbstractClass {
|
||||
cb = (s: string) => {};
|
||||
|
||||
constructor(str: string, other: AbstractClass, yetAnother: DerivedAbstractClass) {
|
||||
super(str, other);
|
||||
// there is no implementation of 'prop' in any base class
|
||||
this.cb(this.prop.toLowerCase());
|
||||
~~~~
|
||||
!!! error TS2715: Abstract property 'prop' in class 'AbstractClass' cannot be accessed in the constructor.
|
||||
|
||||
this.method(1);
|
||||
|
||||
// OK, references are to another instance
|
||||
other.cb(other.prop);
|
||||
yetAnother.cb(yetAnother.prop);
|
||||
}
|
||||
}
|
||||
|
||||
class Implementation extends DerivedAbstractClass {
|
||||
prop = "";
|
||||
cb = (s: string) => {};
|
||||
|
||||
constructor(str: string, other: AbstractClass, yetAnother: DerivedAbstractClass) {
|
||||
super(str, other, yetAnother);
|
||||
this.cb(this.prop);
|
||||
}
|
||||
|
||||
method(n: number) {
|
||||
this.cb(this.prop + n);
|
||||
}
|
||||
}
|
||||
|
||||
class User {
|
||||
constructor(a: AbstractClass) {
|
||||
a.prop;
|
||||
|
||||
@ -31,6 +31,36 @@ abstract class AbstractClass {
|
||||
}
|
||||
}
|
||||
|
||||
abstract class DerivedAbstractClass extends AbstractClass {
|
||||
cb = (s: string) => {};
|
||||
|
||||
constructor(str: string, other: AbstractClass, yetAnother: DerivedAbstractClass) {
|
||||
super(str, other);
|
||||
// there is no implementation of 'prop' in any base class
|
||||
this.cb(this.prop.toLowerCase());
|
||||
|
||||
this.method(1);
|
||||
|
||||
// OK, references are to another instance
|
||||
other.cb(other.prop);
|
||||
yetAnother.cb(yetAnother.prop);
|
||||
}
|
||||
}
|
||||
|
||||
class Implementation extends DerivedAbstractClass {
|
||||
prop = "";
|
||||
cb = (s: string) => {};
|
||||
|
||||
constructor(str: string, other: AbstractClass, yetAnother: DerivedAbstractClass) {
|
||||
super(str, other, yetAnother);
|
||||
this.cb(this.prop);
|
||||
}
|
||||
|
||||
method(n: number) {
|
||||
this.cb(this.prop + n);
|
||||
}
|
||||
}
|
||||
|
||||
class User {
|
||||
constructor(a: AbstractClass) {
|
||||
a.prop;
|
||||
@ -42,6 +72,19 @@ class User {
|
||||
|
||||
|
||||
//// [abstractPropertyInConstructor.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 (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
}
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
var AbstractClass = /** @class */ (function () {
|
||||
function AbstractClass(str, other) {
|
||||
var _this = this;
|
||||
@ -65,6 +108,35 @@ var AbstractClass = /** @class */ (function () {
|
||||
};
|
||||
return AbstractClass;
|
||||
}());
|
||||
var DerivedAbstractClass = /** @class */ (function (_super) {
|
||||
__extends(DerivedAbstractClass, _super);
|
||||
function DerivedAbstractClass(str, other, yetAnother) {
|
||||
var _this = _super.call(this, str, other) || this;
|
||||
_this.cb = function (s) { };
|
||||
// there is no implementation of 'prop' in any base class
|
||||
_this.cb(_this.prop.toLowerCase());
|
||||
_this.method(1);
|
||||
// OK, references are to another instance
|
||||
other.cb(other.prop);
|
||||
yetAnother.cb(yetAnother.prop);
|
||||
return _this;
|
||||
}
|
||||
return DerivedAbstractClass;
|
||||
}(AbstractClass));
|
||||
var Implementation = /** @class */ (function (_super) {
|
||||
__extends(Implementation, _super);
|
||||
function Implementation(str, other, yetAnother) {
|
||||
var _this = _super.call(this, str, other, yetAnother) || this;
|
||||
_this.prop = "";
|
||||
_this.cb = function (s) { };
|
||||
_this.cb(_this.prop);
|
||||
return _this;
|
||||
}
|
||||
Implementation.prototype.method = function (n) {
|
||||
this.cb(this.prop + n);
|
||||
};
|
||||
return Implementation;
|
||||
}(DerivedAbstractClass));
|
||||
var User = /** @class */ (function () {
|
||||
function User(a) {
|
||||
a.prop;
|
||||
|
||||
@ -92,31 +92,134 @@ abstract class AbstractClass {
|
||||
}
|
||||
}
|
||||
|
||||
abstract class DerivedAbstractClass extends AbstractClass {
|
||||
>DerivedAbstractClass : Symbol(DerivedAbstractClass, Decl(abstractPropertyInConstructor.ts, 30, 1))
|
||||
>AbstractClass : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0))
|
||||
|
||||
cb = (s: string) => {};
|
||||
>cb : Symbol(DerivedAbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 32, 59))
|
||||
>s : Symbol(s, Decl(abstractPropertyInConstructor.ts, 33, 10))
|
||||
|
||||
constructor(str: string, other: AbstractClass, yetAnother: DerivedAbstractClass) {
|
||||
>str : Symbol(str, Decl(abstractPropertyInConstructor.ts, 35, 16))
|
||||
>other : Symbol(other, Decl(abstractPropertyInConstructor.ts, 35, 28))
|
||||
>AbstractClass : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0))
|
||||
>yetAnother : Symbol(yetAnother, Decl(abstractPropertyInConstructor.ts, 35, 50))
|
||||
>DerivedAbstractClass : Symbol(DerivedAbstractClass, Decl(abstractPropertyInConstructor.ts, 30, 1))
|
||||
|
||||
super(str, other);
|
||||
>super : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0))
|
||||
>str : Symbol(str, Decl(abstractPropertyInConstructor.ts, 35, 16))
|
||||
>other : Symbol(other, Decl(abstractPropertyInConstructor.ts, 35, 28))
|
||||
|
||||
// there is no implementation of 'prop' in any base class
|
||||
this.cb(this.prop.toLowerCase());
|
||||
>this.cb : Symbol(DerivedAbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 32, 59))
|
||||
>this : Symbol(DerivedAbstractClass, Decl(abstractPropertyInConstructor.ts, 30, 1))
|
||||
>cb : Symbol(DerivedAbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 32, 59))
|
||||
>this.prop.toLowerCase : Symbol(String.toLowerCase, Decl(lib.es5.d.ts, --, --))
|
||||
>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5))
|
||||
>this : Symbol(DerivedAbstractClass, Decl(abstractPropertyInConstructor.ts, 30, 1))
|
||||
>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5))
|
||||
>toLowerCase : Symbol(String.toLowerCase, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
this.method(1);
|
||||
>this.method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 20, 37))
|
||||
>this : Symbol(DerivedAbstractClass, Decl(abstractPropertyInConstructor.ts, 30, 1))
|
||||
>method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 20, 37))
|
||||
|
||||
// OK, references are to another instance
|
||||
other.cb(other.prop);
|
||||
>other.cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 19, 26))
|
||||
>other : Symbol(other, Decl(abstractPropertyInConstructor.ts, 35, 28))
|
||||
>cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 19, 26))
|
||||
>other.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5))
|
||||
>other : Symbol(other, Decl(abstractPropertyInConstructor.ts, 35, 28))
|
||||
>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5))
|
||||
|
||||
yetAnother.cb(yetAnother.prop);
|
||||
>yetAnother.cb : Symbol(DerivedAbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 32, 59))
|
||||
>yetAnother : Symbol(yetAnother, Decl(abstractPropertyInConstructor.ts, 35, 50))
|
||||
>cb : Symbol(DerivedAbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 32, 59))
|
||||
>yetAnother.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5))
|
||||
>yetAnother : Symbol(yetAnother, Decl(abstractPropertyInConstructor.ts, 35, 50))
|
||||
>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5))
|
||||
}
|
||||
}
|
||||
|
||||
class Implementation extends DerivedAbstractClass {
|
||||
>Implementation : Symbol(Implementation, Decl(abstractPropertyInConstructor.ts, 46, 1))
|
||||
>DerivedAbstractClass : Symbol(DerivedAbstractClass, Decl(abstractPropertyInConstructor.ts, 30, 1))
|
||||
|
||||
prop = "";
|
||||
>prop : Symbol(Implementation.prop, Decl(abstractPropertyInConstructor.ts, 48, 51))
|
||||
|
||||
cb = (s: string) => {};
|
||||
>cb : Symbol(Implementation.cb, Decl(abstractPropertyInConstructor.ts, 49, 14))
|
||||
>s : Symbol(s, Decl(abstractPropertyInConstructor.ts, 50, 10))
|
||||
|
||||
constructor(str: string, other: AbstractClass, yetAnother: DerivedAbstractClass) {
|
||||
>str : Symbol(str, Decl(abstractPropertyInConstructor.ts, 52, 16))
|
||||
>other : Symbol(other, Decl(abstractPropertyInConstructor.ts, 52, 28))
|
||||
>AbstractClass : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0))
|
||||
>yetAnother : Symbol(yetAnother, Decl(abstractPropertyInConstructor.ts, 52, 50))
|
||||
>DerivedAbstractClass : Symbol(DerivedAbstractClass, Decl(abstractPropertyInConstructor.ts, 30, 1))
|
||||
|
||||
super(str, other, yetAnother);
|
||||
>super : Symbol(DerivedAbstractClass, Decl(abstractPropertyInConstructor.ts, 30, 1))
|
||||
>str : Symbol(str, Decl(abstractPropertyInConstructor.ts, 52, 16))
|
||||
>other : Symbol(other, Decl(abstractPropertyInConstructor.ts, 52, 28))
|
||||
>yetAnother : Symbol(yetAnother, Decl(abstractPropertyInConstructor.ts, 52, 50))
|
||||
|
||||
this.cb(this.prop);
|
||||
>this.cb : Symbol(Implementation.cb, Decl(abstractPropertyInConstructor.ts, 49, 14))
|
||||
>this : Symbol(Implementation, Decl(abstractPropertyInConstructor.ts, 46, 1))
|
||||
>cb : Symbol(Implementation.cb, Decl(abstractPropertyInConstructor.ts, 49, 14))
|
||||
>this.prop : Symbol(Implementation.prop, Decl(abstractPropertyInConstructor.ts, 48, 51))
|
||||
>this : Symbol(Implementation, Decl(abstractPropertyInConstructor.ts, 46, 1))
|
||||
>prop : Symbol(Implementation.prop, Decl(abstractPropertyInConstructor.ts, 48, 51))
|
||||
}
|
||||
|
||||
method(n: number) {
|
||||
>method : Symbol(Implementation.method, Decl(abstractPropertyInConstructor.ts, 55, 5))
|
||||
>n : Symbol(n, Decl(abstractPropertyInConstructor.ts, 57, 11))
|
||||
|
||||
this.cb(this.prop + n);
|
||||
>this.cb : Symbol(Implementation.cb, Decl(abstractPropertyInConstructor.ts, 49, 14))
|
||||
>this : Symbol(Implementation, Decl(abstractPropertyInConstructor.ts, 46, 1))
|
||||
>cb : Symbol(Implementation.cb, Decl(abstractPropertyInConstructor.ts, 49, 14))
|
||||
>this.prop : Symbol(Implementation.prop, Decl(abstractPropertyInConstructor.ts, 48, 51))
|
||||
>this : Symbol(Implementation, Decl(abstractPropertyInConstructor.ts, 46, 1))
|
||||
>prop : Symbol(Implementation.prop, Decl(abstractPropertyInConstructor.ts, 48, 51))
|
||||
>n : Symbol(n, Decl(abstractPropertyInConstructor.ts, 57, 11))
|
||||
}
|
||||
}
|
||||
|
||||
class User {
|
||||
>User : Symbol(User, Decl(abstractPropertyInConstructor.ts, 30, 1))
|
||||
>User : Symbol(User, Decl(abstractPropertyInConstructor.ts, 60, 1))
|
||||
|
||||
constructor(a: AbstractClass) {
|
||||
>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 33, 16))
|
||||
>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 63, 16))
|
||||
>AbstractClass : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0))
|
||||
|
||||
a.prop;
|
||||
>a.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5))
|
||||
>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 33, 16))
|
||||
>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 63, 16))
|
||||
>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5))
|
||||
|
||||
a.cb("hi");
|
||||
>a.cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 19, 26))
|
||||
>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 33, 16))
|
||||
>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 63, 16))
|
||||
>cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 19, 26))
|
||||
|
||||
a.method(12);
|
||||
>a.method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 20, 37))
|
||||
>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 33, 16))
|
||||
>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 63, 16))
|
||||
>method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 20, 37))
|
||||
|
||||
a.method2();
|
||||
>a.method2 : Symbol(AbstractClass.method2, Decl(abstractPropertyInConstructor.ts, 25, 25))
|
||||
>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 33, 16))
|
||||
>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 63, 16))
|
||||
>method2 : Symbol(AbstractClass.method2, Decl(abstractPropertyInConstructor.ts, 25, 25))
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,6 +104,119 @@ abstract class AbstractClass {
|
||||
}
|
||||
}
|
||||
|
||||
abstract class DerivedAbstractClass extends AbstractClass {
|
||||
>DerivedAbstractClass : DerivedAbstractClass
|
||||
>AbstractClass : AbstractClass
|
||||
|
||||
cb = (s: string) => {};
|
||||
>cb : (s: string) => void
|
||||
>(s: string) => {} : (s: string) => void
|
||||
>s : string
|
||||
|
||||
constructor(str: string, other: AbstractClass, yetAnother: DerivedAbstractClass) {
|
||||
>str : string
|
||||
>other : AbstractClass
|
||||
>yetAnother : DerivedAbstractClass
|
||||
|
||||
super(str, other);
|
||||
>super(str, other) : void
|
||||
>super : typeof AbstractClass
|
||||
>str : string
|
||||
>other : AbstractClass
|
||||
|
||||
// there is no implementation of 'prop' in any base class
|
||||
this.cb(this.prop.toLowerCase());
|
||||
>this.cb(this.prop.toLowerCase()) : void
|
||||
>this.cb : (s: string) => void
|
||||
>this : this
|
||||
>cb : (s: string) => void
|
||||
>this.prop.toLowerCase() : string
|
||||
>this.prop.toLowerCase : () => string
|
||||
>this.prop : string
|
||||
>this : this
|
||||
>prop : string
|
||||
>toLowerCase : () => string
|
||||
|
||||
this.method(1);
|
||||
>this.method(1) : void
|
||||
>this.method : (num: number) => void
|
||||
>this : this
|
||||
>method : (num: number) => void
|
||||
>1 : 1
|
||||
|
||||
// OK, references are to another instance
|
||||
other.cb(other.prop);
|
||||
>other.cb(other.prop) : void
|
||||
>other.cb : (s: string) => void
|
||||
>other : AbstractClass
|
||||
>cb : (s: string) => void
|
||||
>other.prop : string
|
||||
>other : AbstractClass
|
||||
>prop : string
|
||||
|
||||
yetAnother.cb(yetAnother.prop);
|
||||
>yetAnother.cb(yetAnother.prop) : void
|
||||
>yetAnother.cb : (s: string) => void
|
||||
>yetAnother : DerivedAbstractClass
|
||||
>cb : (s: string) => void
|
||||
>yetAnother.prop : string
|
||||
>yetAnother : DerivedAbstractClass
|
||||
>prop : string
|
||||
}
|
||||
}
|
||||
|
||||
class Implementation extends DerivedAbstractClass {
|
||||
>Implementation : Implementation
|
||||
>DerivedAbstractClass : DerivedAbstractClass
|
||||
|
||||
prop = "";
|
||||
>prop : string
|
||||
>"" : ""
|
||||
|
||||
cb = (s: string) => {};
|
||||
>cb : (s: string) => void
|
||||
>(s: string) => {} : (s: string) => void
|
||||
>s : string
|
||||
|
||||
constructor(str: string, other: AbstractClass, yetAnother: DerivedAbstractClass) {
|
||||
>str : string
|
||||
>other : AbstractClass
|
||||
>yetAnother : DerivedAbstractClass
|
||||
|
||||
super(str, other, yetAnother);
|
||||
>super(str, other, yetAnother) : void
|
||||
>super : typeof DerivedAbstractClass
|
||||
>str : string
|
||||
>other : AbstractClass
|
||||
>yetAnother : DerivedAbstractClass
|
||||
|
||||
this.cb(this.prop);
|
||||
>this.cb(this.prop) : void
|
||||
>this.cb : (s: string) => void
|
||||
>this : this
|
||||
>cb : (s: string) => void
|
||||
>this.prop : string
|
||||
>this : this
|
||||
>prop : string
|
||||
}
|
||||
|
||||
method(n: number) {
|
||||
>method : (n: number) => void
|
||||
>n : number
|
||||
|
||||
this.cb(this.prop + n);
|
||||
>this.cb(this.prop + n) : void
|
||||
>this.cb : (s: string) => void
|
||||
>this : this
|
||||
>cb : (s: string) => void
|
||||
>this.prop + n : string
|
||||
>this.prop : string
|
||||
>this : this
|
||||
>prop : string
|
||||
>n : number
|
||||
}
|
||||
}
|
||||
|
||||
class User {
|
||||
>User : User
|
||||
|
||||
|
||||
@ -30,6 +30,36 @@ abstract class AbstractClass {
|
||||
}
|
||||
}
|
||||
|
||||
abstract class DerivedAbstractClass extends AbstractClass {
|
||||
cb = (s: string) => {};
|
||||
|
||||
constructor(str: string, other: AbstractClass, yetAnother: DerivedAbstractClass) {
|
||||
super(str, other);
|
||||
// there is no implementation of 'prop' in any base class
|
||||
this.cb(this.prop.toLowerCase());
|
||||
|
||||
this.method(1);
|
||||
|
||||
// OK, references are to another instance
|
||||
other.cb(other.prop);
|
||||
yetAnother.cb(yetAnother.prop);
|
||||
}
|
||||
}
|
||||
|
||||
class Implementation extends DerivedAbstractClass {
|
||||
prop = "";
|
||||
cb = (s: string) => {};
|
||||
|
||||
constructor(str: string, other: AbstractClass, yetAnother: DerivedAbstractClass) {
|
||||
super(str, other, yetAnother);
|
||||
this.cb(this.prop);
|
||||
}
|
||||
|
||||
method(n: number) {
|
||||
this.cb(this.prop + n);
|
||||
}
|
||||
}
|
||||
|
||||
class User {
|
||||
constructor(a: AbstractClass) {
|
||||
a.prop;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user