假設我們有一些 JavaNode和StringNode類NodeFactory:
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
有沒有一種型別安全的方法可以在打字稿中撰寫這樣的工廠方法?
uj5u.com熱心網友回復:
類的泛型引數適用于實體而不是靜態類本身。也value適用于實體。所以NodeClass需要是一個“新的”型別,它回傳一個具有正確泛型的實體。
這意味著這將起作用:
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)是一個不錯的獎勵。TypescriptT從第二個引數中提取,并將其放入NodeClassfor you.
操場
uj5u.com熱心網友回復:
我找到了一個解決方案:
public static createNode<N extends { new(): Node<T> }, T>(NodeClass: N, value: T): Node<T> {
顯然我只需要 N 來實作一個帶有new(): Node<T>方法(或建構式)的介面。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/426096.html
