如何在具有泛型类型参数的函数中引用具有私有构造函数的类?

Mys*_*son 5 private-constructor typescript

我有一个基类和多个扩展该基类的类,它们都有一个私有构造函数。

我现在想创建一个静态函数来创建扩展类的新实例。通常我会有一个类似这样的函数头:

public static createInstance<T extends BaseClass>(clazz: { new(): T }): T
Run Code Online (Sandbox Code Playgroud)

当我想使用这个功能时:

createInstance(CustomClass)
Run Code Online (Sandbox Code Playgroud)

它会导致打字稿吐出此错误:

TS2345:“typeof CustomClass”类型的参数不可分配给“new () => CustomClass”类型的参数。无法将“私有”构造函数类型分配给“公共”构造函数类型。

代码实际转译的代码工作得很好。

我知道这个错误告诉我什么。但我找不到解决这个问题的方法。我已经搜索了很多,而且我似乎很孤独地遇到这个问题。有什么方法可以引用带有私有构造函数的类吗?

Ole*_*ter 1

您的问题的解决方案出人意料地简单:不要将泛型类型参数限制T为类的实例类型Base,而是通过类型查询将其限制为类的静态(或构造函数)端typeof Base

这将确保clazz将被推断为具体类型的构造函数类型T而不是公共构造函数类型(new (): T),有效地绕过私有构造函数检查,同时保留泛型约束的好处:

abstract class Abstract {}

class Base { answer = 42; }

class Custom extends Base {
  private constructor() { super(); }
}

class Unrelated {}

declare function createInstance<T extends typeof Base>(clazz: T): InstanceType<T>;

createInstance(Abstract); // error, OK
createInstance(Base); // OK
createInstance(Custom); // OK
createInstance(Unrelated); // error, OK
Run Code Online (Sandbox Code Playgroud)

操场