2016-05-31 11 views
14

私は、Typescriptでインタフェースを使用して、基本クラスを拡張するいくつかのクラスでのみ使用できる関数を定義しています。そうmoveAnimal機能が大きくなりすぎますTypeScript - クラスがインタフェースを実装しているかどうかを確認します。

class Animal { 
} 

interface IWalkingAnimal { 
    walk(): void; 
} 

class Dog extends Animal implements IWalkingAnimal { 
} 

class Cat extends Animal implements IWalkingAnimal { 
} 

class Snake extends Animal { 
} 

private moveAnimal(animal: Animal) { 
    if (animal instanceof Cat || animal instanceof Dog) { 
     animal.walk(); 
    } 
} 

さて、トラブルが、私が追加されますされ、より「歩く」動物が管理可能にする:これは私がこれまで持っているコードの簡易版です。 「道具」のチェックが機能しない、と私はインターフェイスを使用したときに「instanceofは」に相当するものを見つけることができませんしかし

private moveAnimal(animal: Animal) { 
    if (animal implements IWalkingAnimal) { 
     animal.walk(); 
    } 
} 

:私は何をしたいのは、このようなものです。 Javaでは、 'instanceof'の使用はここではうまくいくようですが、TypeScriptはこれを許可しません。

このようなことがTypeScriptに存在するのでしょうか、それとももっと良いアプローチがありますか?私はTypeScript 1.8.9を使用しています。

+0

「IWalkingAnimal」は、インターフェイスではなく、Animalのサブクラスではありません。そうすれば、問題は起こらず、意味をなさないでしょう。 – iberbeu

+0

@iberbeuこれは、この単純化された例ではうまくいくでしょう。柔軟性のためにIWalkingAnimalをインターフェイスにして、Animalに厳密に束縛されていないようにします。下のThiloの答えはそのトリックを行うべきです。 – MarkLunney

+1

[Interface type check with Typescript]の可能な複製(https://stackoverflow.com/questions/14425568/interface-type-check-with-typescript) –

答えて

24

クラスとは異なり、インターフェイスはコンパイル時にのみ存在し、結果のJavascriptには含まれないため、instanceofのチェックはできません。

あなたは動物のIWalkingAnimalサブクラスを作る(およびinstanceofを使用)、または問題のオブジェクトがwalkメソッドを持っている場合は、チェックすることができ可能性:

if (animal['walk']) {} 

あなたはuser defined type guardでこれをラップすることができます(ようにコンパイラは、instanceofと同様に、if文で使用すると型を絞り込むことができます。

/** 
* User Defined Type Guard! 
*/ 
function canWalk(arg: Animal): arg is IWalkingAnimal { 
    return (arg as IWalkingAnimal).walk !== undefined; 
} 


private moveAnimal(animal: Animal) { 
    if (canWalk(animal)) { 
     animal.walk(); // compiler knows it can walk now 
    } 
} 
+2

'(arg as IWalkingAnimal).walk'を実行することをお勧めしますwalkメソッドの名前を変更する場合は、型ガードのコードも同様に変更されます。 –

関連する問題