Home > Software engineering >  Class<?> type for abstract classes in TypeScript
Class<?> type for abstract classes in TypeScript

Time:05-18

In TypeScript I use Java like type Class:

interface Class<T = void> {

    new(...args: any[]): T;

}

However, such type doesn't work with abstract classes:

abstract class Bar {}

class Foo {
   
  test(clazz: Class) { }

  doIt() {
    this.test(Bar);//ERROR
  }
}

The error I get is Argument of type 'typeof Bar' is not assignable to parameter of type 'Class<void>'. When class Bar is not abstract then everything is ok.

I understand, that the problem is that declaring Class we say it is possible to use new operator, but we can't use this operator for abstract classes. However, I need a type, that could be suitable both for non abstract and abstract classes (abstract classes are classes too). If it is possible, could anyone say how to do it?

CodePudding user response:

You can use an abstract construct signature:

type Class<T = void> =
  abstract new (...args: any[]) => T;

You can assign both a regular/concrete contructor and an abstract constructor to such a signature, as desired:

abstract class Bar { }
class Baz { }

class Foo {

  test(clazz: Class) { }

  doIt() {
    this.test(Bar); // okay
    this.test(Baz); // okay
  }
}

Note that, for whatever reason, abstract construct signatures must be in the form of an arrow construct expression (like a function expression); you can't put abstract before new in an object-like construct signature:

interface Oops<T = void> {
  abstract new(...args: any[]): T; // error!
  //~~~~~~ <-- 'abstract' modifier cannot appear on a type member
}

Playground link to code

  • Related