很抱歉这个奇怪的标题,我不知道如何用一句话描述我想要做的事情。
我必须定义一堆类,这些类都将从这一个类扩展,并实现另一个类。
class SoulCoughing extends Super implements BonBon { /.../ }
class MoveAside extends Super implements BonBon { /.../ }
class LetTheManGoThru extends Super implements BonBon { /.../ }
我编写了一种包装函数,我将其用作这些类的装饰器。
const Eminem = function(klass: Constructable<????>) {
const instance = new klass();
// Do stuff
}
Constructable
是我正在使用的一个小界面,因为否则TypeScript会抛出一个关于没有构造函数的错误。
interface Constructable<T> {
new(): T;
}
现在这是我的问题,我不知道在我的包装函数中分配给参数klass
的类型是什么?我试过这样做:
... function(klass: Contrusctable<Super & BonBon>)
和此:
... function(klass: Contrusctable<Super | BonBon>)
我也试过像这样修改我的可构造界面:
interface Constructable<T, U> {
new(): T & U;
}
... function(klass: Contrusctable<Super, BonBon>)
但我一直收到Argument of type 'typeof SoulCoughing' is not assignable to parameter of type 'Constructable<everythingIveTriedSoFar>'
错误。
所以我的问题是,我应该使用参数klass
来定义什么类型的定义?我知道我可以使用any
,但我确实希望确保传递的类已扩展Super
并实施BonBon
。
答案 0 :(得分:1)
我猜测班级SoulCoughing
等实际上没有非参数构造函数,因此根本不能充当Constructable<{}>
;最可能的罪魁祸首是Super
的构造函数具有强制参数,这将使所有子类默认情况下无法匹配new()
。请注意,这也意味着您的Eminem
实现可能也希望使用一些参数调用new klass(...)
。
修复它的正确方法是将Constructable<T>
声明为具有正确参数类型的构造函数。让我们说Super
看起来像这样:
class Super {
constructor(elevator: number, mezzanine: string) {
//...
}
}
然后您可以定义Constructable
来匹配:
interface Constructable<T extends Super & BonBon = Super & BonBon> {
new(chump: number, change: string): T; // same args as Super
}
和Eminem
喜欢:
const Eminem = function(klass: Constructable) {
const instance = new klass(2, "rise");
// Do stuff
}
最后:
Eminem(SoulCoughing); // no error
我只保留Constructable
通用,以防你希望TypeScript保留特定子类的类型,如下所示:
const SlimShady = function <T extends Super & BonBon>(klass: Constructable<T>): T {
return new klass(2, "fat");
}
// returns same type as passed-in constructor
const cutLean: MoveAside = SlimShady(MoveAside);
好的,希望有所帮助;祝你好运!