2017-10-07 46 views
1

我试图做一个适当的类型安全的二进制树,这里就是我:协变自我指涉的类型

class BinaryNode<N extends BinaryNode<N>> { 
    constructor(left?: N, right?: N) {} 
} 

class A extends BinaryNode<A> { } 
class B extends BinaryNode<B> { } 


const leafA = new A(); 
const leafB = new B(); 
const rootA = new A(leafA, leafB); 

的问题是,这个编译。我认为它不应该:A承包商应该采取两个(或更少)As,而不是其他任何东西。

更重要的是,如何我这样做?我希望结果是由编译器强制执行的As的同构树。

回答

3

TypeScript类型系统是structural。这意味着对于类型检查,您的AB类是相同的。如果你让他们不同,你会得到错误:

class BinaryNode<N extends BinaryNode<N>> { 
    constructor(left?: N, right?: N) {} 
} 

class A extends BinaryNode<A> { a: string } 
class B extends BinaryNode<B> { b: string } 


const leafA = new A(); 
const leafB = new B(); 
const rootA = new A(leafA, leafB); // Argument of type 'B' is not 
            // assignable to parameter of type 'A'. 
            // Property 'a' is missing in type 'B'.