如何正确应用泛型静态方法的泛型类型定义?

问题描述 投票:1回答:1

我有以下基类和派生类。

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>;
typescript generics static-methods
1个回答
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应该是首选。

© www.soinside.com 2019 - 2024. All rights reserved.