Reputation: 923
The abstract class ParentClass
in the code below need to work with abstract property significantEntity
(which is the instance on the class, inherited from abstract SignificantEntityParent
). Off course, below code is invalid, because significantEntity
implementations has different type than SignificantEntityParent
.
abstract class SignificantEntityParent {}
class SignificantEntity1 extends SignificantEntityParent {}
class SignificantEntity2 extends SignificantEntityParent {}
abstract class ParentClass {
protected abstract significantEntity: SignificantEntityParent;
public testMethod(): void {
console.log(this.significantEntity);
}
}
class TestClass1 extends ParentClass {
constructor() {
super();
// invalid!
this.significantEntity = new SignificantEntity1();
}
}
class TestClass2 extends ParentClass {
constructor() {
super();
// invalid!
this.significantEntity = new SignificantEntity2();
}
}
I tried walk-around with abstract generic method getSignificantEntity<SignificantEntity extends SignificantEntityParent>(): SignificantEntity
.
abstract class ParentClassA {
protected abstract getSignificantEntity<SignificantEntity extends SignificantEntityParent>(): SignificantEntity;
public logSignificantEntity(): void {
console.log(this.getSignificantEntity());
}
}
class TestClassA1 extends ParentClassA {
private significantEntity: SignificantEntity1;
constructor() {
super();
this.significantEntity = new SignificantEntity1();
}
protected getSignificantEntity(): SignificantEntity1 {
return this.significantEntity;
}
}
class TestClassA2 extends ParentClassA {
private significantEntity: SignificantEntity2;
constructor() {
super();
this.significantEntity = new SignificantEntity2();
}
protected getSignificantEntity(): SignificantEntity2 {
return this.significantEntity;
}
}
I get a lot of errors:
I can not understand what TypeScript trying to tell me. Is there valid approach to work with significantEntity
inside abstract class?
Upvotes: 1
Views: 1040
Reputation: 327819
It might not be clearly documented, but the abstract properties and methods of abstract classes have to be declared in concrete subclasses; they can't just be used. That means you can fix your first example by adding concrete property declarations:
class TestClass1 extends ParentClass {
significantEntity: SignificantEntity1; // declaration
constructor() {
super();
this.significantEntity = new SignificantEntity1();
}
}
class TestClass2 extends ParentClass {
significantEntity: SignificantEntity2; // declaration
constructor() {
super();
this.significantEntity = new SignificantEntity2();
}
}
Of course, if all you're doing in the constructor is initializing a property, you can drop the constructor and use an explicit property initializer, which serves as both declaration and initialization:
class TestClass1 extends ParentClass {
significantEntity = new SignificantEntity1();
}
class TestClass2 extends ParentClass {
significantEntity= new SignificantEntity2();
}
Okay, hope that helps. Good luck!
Upvotes: 3