Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript type of concrete subclasses of an abstract class

I'm trying to resolve this specific case in Typescript:

Typescript Playground link

abstract class foo {
    abstract bar();
}

class Foo1 extends foo {
    bar() {
        alert(1);
    }

    y: number = 3;
}

class Foo2 extends foo {
    bar() {
        alert(2);
    }
}

let myFooClasses: Array<typeof foo> = [];
myFooClasses.push(Foo1);
myFooClasses.push(Foo2);

myFooClasses.forEach((item) => {
    let a = new item();
    a.bar();
})

Specifically, the problem is that myFooClasses could technically contain foo which is abstract and Typescript warns about this. But I really want to constrain the type of myFooClasses to concrete classes inheriting from foo. Is there any way of specifying this in Typescript?

like image 940
gwk Avatar asked Jun 03 '16 15:06

gwk


1 Answers

Your array type should be:

let myFooClasses: Array<{ new (): foo }> = [];

and then this:

myFooClasses.push(foo);

produces this error:

Argument of type 'typeof foo' is not assignable to parameter of type '{ new (): foo }'. Can not assign an abstract constructor type to a non-abstract constructor type.

You can also do:

type FooConstructor = { new (): foo };
let myFooClasses: FooConstructor[] = [];
like image 163
Nitzan Tomer Avatar answered Sep 28 '22 10:09

Nitzan Tomer