抽象类和扩展器的类型

时间:2019-05-09 06:44:43

标签: typescript

所以我有几节课

abstract class Base {
  private readonly prop = "abc";
}

class One extends Base {
  // ...
}

class Two extends Base {
  // ...
}

,我想创建一个类型,以便我可以存储Base类或扩展它的任何类(而不是它们的实例)。首先,我认为仅let c: Base会起作用,但显然希望该类的实例而不是类本身。然后,我尝试了let c: typeof Base,但是当给该变量分配One时,tsc会生成错误。那么我应该在变量c中使用哪种类型?

1 个答案:

答案 0 :(得分:1)

由于Base是抽象类,所以typeof Base实际上将不包含可调用的构造函数签名,而仅包含该类的静态变量和原型。这通常是一件好事,因为我们要禁止类型的实例化。

您可以将typeof Base与构造函数签名相交,这将具有覆盖基本构造函数的效果:

abstract class Base {
  public constructor(private readonly prop = "abc") { }
}

class One extends Base {
  p: string;
}

class Two extends Base {
  p2: string;
}

declare let ctor: typeof Base & (new (...a: any[]) => Base); 
new ctor("") // ok
class D extends ctor { } // ok
ctor = One; //ok

此解决方案将迫使您在要分配的派生类中具有相同的构造函数签名,所以这是错误的

abstract class Base {
  public constructor(private readonly prop = "abc") { }
}

class One extends Base {
  public constructor(prop: string, p: string) {
    super(prop)
  }
}

declare let ctor: typeof Base & (new (...a: any[]) => Base);
ctor = One; //err, new One requires more params

如果您不需要Base的静态信息,则可以使用构造函数签名

declare let ctor: new (...a: any[]) => Base;
ctor = One; //ok for any derived type regardless of ctor params.