我有一个班级
class Node {
children: Node[];
}
由其他几个类继承
class Block extends Node {
// ...
}
在所有继承的类中,我希望有一个名为replaceChild的函数:
const block = new Block();
block.replaceChild(oldChild, newChild);
我不想在所有继承的类中实现此函数(duh!)。这里的线索是我的类是不可变的,所以我没有改变类,而是想要返回一个带有更改children
的新实例。问题是,我想在replaceChild
中实现的函数Node
不应该返回Node
实例,而是返回继承类的实例:
class Node {
children: Node[];
replaceChild(oldChild, newChild): Node {
// ...
return new Node(/* ... */)
}
}
class Block extends Node {
// ...
}
const block = new Block();
const newMutatedBlock: Block = block.replaceChild(oldChild, newChild);
我正在使用TypeScript
。如何告诉TypeScript(每次没有进行类型转换)replaceChild
节点上的方法Block
返回Block
而不是Node
?
答案 0 :(得分:4)
您正在寻找polymorphic this
,这是一种与this
对象相对应的类型。而不是说replaceChild()
返回类型Node
,而是说它返回类型this
。
请注意,您不能在new Node()
的实现中调用replaceChild()
,因为这不会正确创建子类。幸运的是,类的实例包含对其构造函数的引用,因此您可以调用new this.constructor()
。不幸的是,除了this.constructor
之外,TypeScript对Function
一无所知。幸运的是,您可以声明this.constructor
具有类型new()=>this
并安全使用它。 (由您来正确声明参数类型并确保所有子类构造函数采用相同的参数类型)。这是它的外观:
class Node {
children: Node[];
"constructor": new (/* ... */) => this;
replaceChild(oldChild, newChild): this {
// ...
return new this.constructor(/* ... */)
}
}
我不确定oldChild
和newChild
是否也应该是this
,或Node
,或者是什么。你必须决定。
现在测试:
class Block extends Node {
// ...
}
const block = new Block();
const newMutatedBlock: Block = block.replaceChild(oldChild, newChild);
这有效(假设oldChild
和newChild
存在并且是正确的类型),因为Block.replaceChild()
会返回Block
而不只是Node
。< / p>
希望有所帮助;祝你好运!