属性的实例类型是实例本身的构造函数,即打字稿

时间:2019-10-15 12:09:59

标签: typescript

我正在用Typescript做BinaryTree的东西,所以我有以下内容:

class BinaryTreeNode {
    left: BinaryTreeNode;
    right: BinaryTreeNode;
    parent: BinaryTreeNode;
}

class BinarySearchNode extends BinaryTreeNode {
    left: BinarySearchNode; //I have to rewrite those property types
}

那么可以将实例的属性类型引用到实例的构造函数吗?

2 个答案:

答案 0 :(得分:2)

也许是这样吗?

class Tree<T> {
  left: Tree<T>;
  right: Tree<T>;
  parent: Tree<T>
}

class BinaryNode {
    // node data
}

class BinaryTree extends Tree<BinaryNode> {

}

let tree = new BinaryTree();

我不确定是否要从节点中分离树,这取决于要在这些对象中存储哪些信息。

如果您想要与您的实现“相同”,则可以执行以下操作:

class TreeNode<T extends TreeNode<T>> {
  left: T;
  right: T;
  parent: T
}

class BinaryTree extends TreeNode<BinaryTree> {

}

let tree = new BinaryTree();

答案 1 :(得分:1)

根据您的实际代码,您可能正在寻找polymorphic this type,这是this在类的实际实例中甚至在子类中将具有的类型:

class BinaryTreeNode {
  left: this;
  right: this;
  parent: this;  
}

(此外:请注意,如果您使用--strict compiler option,则上面的代码以及原始示例代码也会出现编译器错误。您没有初始化类属性,因此在运行时我可能会期望在引用undefined时出现一些错误。根树节点可能没有父节点,叶子没有子节点,因此您可能希望props是可选的。但这不在问题范围内。)

然后,您的子类不需要任何特殊处理即可表现出您想要的方式:

class BinarySearchNode extends BinaryTreeNode {
  someProp = "okay"; // stucturally identical classes are indistinguishable   
}

(此外:我在子类中添加了一个属性,以使其与父类在结构上有所区别。TypeScript的类型系统是结构性的,而不是名义上的。具有相同结构但名称不同的两种类型实际上是同一类型。This can cause surprising results因此即使在示例代码中,也要避免使用任何空的类定义。)

让我们对其进行测试:

const btn = new BinaryTreeNode().left;
// const btn: BinaryTreeNode

const bsn = new BinarySearchNode().left;
// const bsn: BinarySearchNode

您会看到btnbsn的类型分别自动为BinaryTreeNodeBinarySearchNode

希望有所帮助;祝你好运!

Link to code