2016-05-31 332 views
14

我正在使用Typescript中的接口來定義僅在某些擴展基類的類上可用的函數。這是代碼的簡化版本,我到目前爲止有: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(); 
    } 
} 

現在,麻煩的是我會增加更多的「走」的動物,因此moveAnimal功能將增長過大,是可控的。我想這樣做是這樣的:

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

然而,「工具」檢查不工作,以及使用接口時,我找不到一個相當於「的instanceof」。在Java中,'instanceof'的使用似乎可以在這裏工作,但TypeScript不允許這樣做。

TypeScript中是否存在這樣的事情,或者這裏有更好的方法嗎?我正在使用TypeScript 1.8.9。

+0

你爲什麼不把'IWalkingAnimal'作爲動物的一個子類而不是界面?這樣你就不會有問題,這是有道理的 – iberbeu

+0

@iberbeu這將適用於這個簡化的例子,爲了靈活性,我想IWalkingAnimal成爲一個界面,所以它不是嚴格依賴於動物。 Thilo的答案應該可以解決問題。 – MarkLunney

+1

[使用Typescript檢查接口類型]可能的重複(https://stackoverflow.com/questions/14425568/interface-type-check-with-typescript) –

回答

24

與類不同,接口僅在編譯時存在,它們不包含在生成的Javascript中,因此您不能執行instanceof檢查。

你可以做IWalkingAnimal動物的子類(和使用instanceof),或者你可以檢查,如果有問題的對象有一個walk方法:

if (animal['walk']) {} 

您可以在user defined type guard把這個包(這樣編譯器可以在if語句中使用時縮小類型,就像instanceof一樣)。

/** 
* 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方法重命名爲其他類型,那麼類型守衛中的代碼也會更改。 –

相關問題