如何使用 `typeof Node<T>` 的泛型类型?

How to use a generic type with `typeof Node<T>`?

假设我们有一些 Java NodeStringNodeNodeFactory 类:

public class Node<T> {
    private T value;

    public void init(T value){
        this.value = value;
    }
}

public class StringNode extends Node<String> {}

public class NodeFactory {
    public static <T> Node<T> createNode(Class<? extends Node<T>> nodeClass, T value) throws Exception {
        Node<T> node = nodeClass.getConstructor().newInstance();
        node.init(value);
        return node;
    }
}

因此 NodeFactory.createNode(StringNode.class, "value1"); 将创建一个 StringNode,其值为:"value1".

我怎么能用打字稿写这样一个工厂方法?

我试着用打字稿写了一个工厂方法:

public static createNode<T>(NodeClass: typeof Node<T>, value: T): Node<T> {
    const node = new NodeClass();
    node.init(value);
    return node;
}

但不接受 typeof Node<T> 通用类型。所以我尝试输入方法的类型参数:

public static createNode<T, N extends Node<T>>(NodeClass: typeof N, value: T): Node<T> {

但编译器也不接受:typeof N: TS2693: 'N' only refers to a type, but is being used as a value here

有没有一种类型安全的方法可以在打字稿中编写这样的工厂方法?

我找到了解决方案:

public static createNode<N extends { new(): Node<T> }, T>(NodeClass: N, value: T): Node<T> {

显然我只需要 N 来实现带有 new(): Node<T> 方法(或构造函数)的接口。

class 的通用参数适用于 实例 而不是静态 class 本身。 value 也用于实例。所以 NodeClass 需要是一个“可更新的”类型,即 returns 具有正确泛型的实例。

这意味着这会起作用:

function createNode<T>(NodeClass: { new (): MyNode<T> }, value: T): MyNode<T> {
    const node = new NodeClass();
    node.init(value)
    return node;
}

测试:

// good
const a = createNode(StringNode, "asd")
const b = createNode(NumberNode, 123)
const c = createNode(FunctionNode, () => 'hello world')
const d = createNode(MyNode, true) // MyNode<boolean>

// error, as expected
const bad = createNode(StringNode, 123)

createNode(MyNode, true) 是一个很好的奖励。 Typescript 从第二个参数中获取 T,并将其放入 NodeClass 中。

Playground