考虑以下代码:
abstract class AbstractFoo {
}
class Foo extends AbstractFoo {
}
class Bar {
getFooConstructor(): typeof AbstractFoo {
return Foo;
}
}
let bar = new Bar();
let FooConstructor = bar.getFooConstructor();
let foo = new FooConstructor();
它无法编译并出现以下错误:
错误TS2511:无法创建抽象类的实例。
这并不意外,因为getFooConstructor
被声明为返回AbstractFoo
构造函数-即抽象构造函数。
如何键入getFooConstructor
返回值,以便TypeScript编译器理解它返回扩展了AbstractFoo
的具体构造函数?
答案 0 :(得分:1)
问题在于打字稿会在类的类型(即typeof AbstractClass
)中记住构造函数是抽象类,因此无法调用。
最简单的解决方案是改用构造函数签名:
abstract class AbstractFoo {
}
class Foo extends AbstractFoo {
}
class Bar {
getFooConstructor(): new ()=> AbstractFoo {
return Foo;
}
}
let bar = new Bar();
let FooConstructor = bar.getFooConstructor();
let foo = new FooConstructor();
虽然这可行,但如果您还需要访问类的静态成员,则不能这样做({getFooConstructor
返回一个构造函数,该构造函数返回从AbstractFoo
派生的东西,而不是实际的类本身)。如果您从抽象类类型派生接口,则可以实现此目的,这将消除构造函数的抽象性,并使我们既可以调用构造函数,又可以访问所有静态成员:
abstract class AbstractFoo {
static m(): void { }
}
type AbstarctFooClass = typeof AbstractFoo;
interface AbstractFooDerived extends AbstarctFooClass { }
class Foo extends AbstractFoo {
}
class Bar {
getFooConstructor(): AbstractFooDerived {
return Foo;
}
}
let bar = new Bar();
let FooConstructor = bar.getFooConstructor();
FooConstructor.m()
let foo = new FooConstructor();