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
}