2017-11-10 11 views
1

TypeScriptのタイプチェックシステムではまだ苦労しています。共通の基底クラスから派生した要素の集合を保持する複合体を考えてみましょう。再帰的に階層を上って、指定された型の最初のオーケストを返す関数を実装するにはどうすればよいですか?任意の助けを事前にタイプのチェックイン階層:getParentOfType()

abstract class Employee 
{ 
    public Superior: Employee; 

    /** THIS IS NOT WORKING */ 
    public getSuperiorOfType<T extends Employee>(type: typeof T): T 
    { 
     if (this instanceof T) return this; 
     else if (this.Superior !== undefined) return this.getSuperiorOfType(type); 
    } 
} 

class Manager extends Employee {} 
class TeamLead extends Employee {} 
class Developer extends Employee {} 

let tom = new Manager(); 
let suzanne = new TeamLead(); 
let ben = new Developer(); 

ben.Superior = suzanne; 
suzanne.Superior = tom; 

let x = ben.getSuperiorOfType(Manager); // x = tom 

おかげで...

答えて

1
  1. 'クラスタイプ' の型はtypeof Tとして宣言することはできません。型の位置にあるtypeofは、型ではなく変数にのみ適用されます。あなたはそのためconstructor signatureいわゆる使用する必要があります。オブジェクトがジェネリック型パラメータのinstanceofある場合

    public getSuperiorOfType<T extends Employee>(type: { new(...args: any[]): T}): T 
    
  2. は、あなたがチェックすることはできません - ジェネリック型パラメータは、実行時に存在しないためinstanceof Tは動作しません。しかし、実際の関数パラメータとしてtypeがあるので、instanceof typeは動作するはずです。

  3. コードに実際の再帰はありません。同じthisオブジェクトの場合、常にgetSuperiorOfTypeを呼び出しています。階層の1つ上に移動するには、this.Superior.getSuperiorOfType(...)と呼ぶ必要があります。

    abstract class Employee 
    { 
        public Superior: Employee; 
    
        public getSuperiorOfType<T extends Employee>(type: { new(...args: any[]): T}): T 
        { 
         if (this instanceof type) return this; 
         else if (this.Superior !== undefined) return this.Superior.getSuperiorOfType(type); 
        } 
    } 
    
    class Manager extends Employee {} 
    class TeamLead extends Employee {} 
    class Developer extends Employee {} 
    
    let tom = new Manager(); 
    let suzanne = new TeamLead(); 
    let ben = new Developer(); 
    
    ben.Superior = suzanne; 
    suzanne.Superior = tom; 
    
    
    let x = ben.getSuperiorOfType(Manager); 
    console.log(x === tom); // true