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

How to refer to a class with private constructor in a function with generic type parameters?

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

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

public static createInstance<T extends BaseClass>(clazz: { new(): T }): T

当我想使用这个功能时:

createInstance(CustomClass)

它导致打字稿吐出这个错误:

TS2345: Argument of type 'typeof CustomClass' is not assignable to parameter of type 'new () => CustomClass'. Cannot assign a 'private' constructor type to a 'public' constructor type.

实际转译后的代码运行良好。

我知道这个错误告诉我什么。但我找不到解决这个问题的方法。我搜索了很多,但似乎只有我一个人遇到这个问题。有什么方法可以用私有构造函数引用 classes 吗?

您的问题的解决方案非常简单:不是将泛型类型参数 T 限制为 实例 类型 Base class,通过 typeof Base 类型查询将其约束到它的 static(或构造函数)一侧。

这将确保 clazz 将被推断为 T 的具体类型的构造函数类型,而不是 public 构造函数类型 (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): T;

createInstance(Abstract); // error, OK
createInstance(Base); // OK
createInstance(Custom); // OK
createInstance(Unrelated); // error, OK

Playground