如何在具有泛型类型参数的函数中引用具有私有构造函数的 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
我有一个基础 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