Reputation: 960
This is my code:
abstract class BaseClass {}
class DerivedClassA extends BaseClass {}
class DerivedClassB extends BaseClass {}
const derivedClasses: (typeof BaseClass)[] = [DerivedClassA, DerivedClassB];
for (const c of derivedClasses) {
const instantiatedObj = new c; // error: Cannot create an instance of an abstract class
}
I have an array of derived classes which I want to iterate and initiate each.
(typeof BaseClass)[]
is not a suitable type. Removing it solves it. What's the correct type?
Upvotes: 1
Views: 308
Reputation: 330216
You can use a construct signature of the form new (arg0: XXX, arg1: YYY) => ZZZ
or { new (arg0: XXX, arg1: YYY): ZZZ }
to represent an object that acts as a class constructor on which you can use the new
operator. In the examples above, you'd pass it two arguments of type XXX
and YYY
and get a class instance of type ZZZ
.
Since you want to call new c()
with no arguments and expect the constructed instances to be assignable to BaseClass
, the type you need is new () => BaseClass
:
const derivedClasses: (new () => BaseClass)[] =
[DerivedClassA, DerivedClassB]; // okay
for (const c of derivedClasses) {
const instantiatedObj = new c(); // okay
}
The compiler is happy to allow you to assign DerivedClassA
and DerivedClassB
to elements of derivedClasses
because each of them can be used as a constructor that takes no arguments and produces an instance of a subtype of Baseclass
. And the compiler is happy to allow you to call new c()
because the construct signature takes no arguments.
Upvotes: 1
Reputation: 558
You can do this:
abstract class BaseClass {}
class DerivedClass extends BaseClass {}
const b: BaseClass = new DerivedClass();
DerivedClass can be treated as a BaseClass given that DerivedClass as the same methods/attributes as BaseClass. And if you want to return to Derived class, you can do this:
if (b instanceof DerivedClass) {
// use DerivedClass methods here
b.customDerivedClassMethod()
}
Upvotes: 0