首页 > 解决方案 > 如何为泛型静态方法正确应用泛型类型定义?

问题描述

我有以下基类和派生类。

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 显示以下错误

类型“typeof DerivedGeneric”不可分配给类型“typeof GenericBase”。
  “DerivedGeneric”类型不能分配给“GenericBase”类型。
    属性“someProp”的类型不兼容。
      类型“日期”不可分配给类型“T”。

对于第二个,它显示以下错误。

类型“类型>”上不存在属性“方法”。

自然,以下工作没有任何编译时错误......

const t3: Function = DerivedGeneric;
(t3 as typeof DerivedGeneric).method("t3");

......以下也是如此,但现在我们遇到了运行时错误。

const t4: Function = () => {};
(t4 as typeof DerivedGeneric).method("t4");

如果没有泛型,第一种方法 ( typeof *Base*) 效果很好。您可以从这个游乐场链接检查。显然,所有方法(除了t4)都在运行时工作,只有编译时错误困扰着我。

有没有办法用泛型来纠正打字?

编辑: 使用以下类型链接到游乐场。

type Type<T> = new (...arg: any[]) => T;
type func = Pick<typeof GenericBase, keyof typeof GenericBase> & Type<GenericBase>;

标签: typescriptgenericsstatic-methods

解决方案


问题是,由于基类有一个泛型类型参数,它的构造函数是一个泛型构造函数。这将是构造函数签名的样子:

const t3 : new <T>(...arg: any[]) => GenericBase<T> = GenericBase

这就是为什么当您尝试分配DerivedGenerictypeof 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无论如何都应该是首选。


推荐阅读