我有以下基类和派生类。
class GenericBase<T = any> {
static method(id: any) {
console.log(`${id}: ${this.name}#method`);
}
public someProp!: T;
}
class DerivedGeneric extends GenericBase<Date> {}
我正在寻找一种正确应用类型定义的方法,该方法将允许我调用静态方法。下面是我到目前为止尝试过的。
const t1: typeof GenericBase = DerivedGeneric;
t1.method("t1");
type Type<T> = new (...arg: any[]) => T;
const t2: Type<GenericBase> = DerivedGeneric;
t2.method("t2");
对于第一个(t1
),TypeScript显示以下错误
Type 'typeof DerivedGeneric' is not assignable to type 'typeof GenericBase'. Type 'DerivedGeneric' is not assignable to type 'GenericBase'. Types of property 'someProp' are incompatible. Type 'Date' is not assignable to type 'T'.
第二个错误显示以下错误。
Property 'method' does not exist on type 'Type>'.
自然,下面的代码可以正常工作,没有任何编译时错误...
const t3: Function = DerivedGeneric;
(t3 as typeof DerivedGeneric).method("t3");
...以下内容也是如此,但是现在我们遇到了运行时错误。
const t4: Function = () => {};
(t4 as typeof DerivedGeneric).method("t4");
没有泛型,第一种方法(typeof *Base*
)效果很好。您可以从此playground link中进行检查。显然,所有方法(t4
除外)都可以在运行时使用,只有编译时错误困扰着我。
有什么办法可以使用泛型来纠正类型?
编辑: Link to playground,具有以下类型。
type Type<T> = new (...arg: any[]) => T;
type func = Pick<typeof GenericBase, keyof typeof GenericBase> & Type<GenericBase>;
答案 0 :(得分:1)
问题在于,由于基类具有通用类型参数,因此其构造函数是通用构造函数。这就是构造函数签名的样子:
const t3 : new <T>(...arg: any[]) => GenericBase<T> = GenericBase
这就是为什么当您尝试将DerivedGeneric
分配给typeof GenericBase
时不能这样做的原因,因为DerivedGeneric
没有这样的泛型构造函数。
如果只需要一个表示类的静态类型的类型,则可以使用Pick
来摆脱typeof GenericBase
中的泛型构造函数签名:
const t1: Pick<typeof GenericBase, keyof typeof GenericBase> = DerivedGeneric; // OK
t1.method("t1");
您还可以创建返回GenericBase<any>
的构造函数和静态成员的交集。
type Type<T> = new (...args: unknown[]) => T;
const t1: Type<GenericBase> & Pick<typeof GenericBase, keyof typeof GenericBase> = DerivedGeneric;
t1.method("t1");
new t1()
注意:它不适用于...args: any[]
,any
有点特殊,不确定它如何发挥作用,但是无论如何都应首选unknown
。