2016-01-15 14 views
2

沒有錯誤下面編譯的打字稿要求論點打字稿是一個(子)的實例類定類的

abstract class Animal { 
    abstract talk() : string ; 
} 

class Chicken extends Animal { 
    talk() : string { return "cluck" ; } 
} 

class Duck extends Animal { 
    talk() : string { return "quack" ; } 
} 

function quack(d : Duck) { 
    console.log(d.talk()) ; 
} 

var a = new Chicken() ; // EDIT: `var a : Chicken = new Chicken()` gives the same result 

quack(a) ; 

我想什麼做的是改變定義ChickenDuck或可能quack的方式使得quack(a)有編譯時錯誤。即Duck類型的參數d應該不能包含Chicken s,也不能包含任何不是Duck的直接或間接實例的其他對象。我知道我可以添加獨特的屬性到ChickenDuck來區分它們。例如。

class Duck extends Animal { 
    onlyInDuck : string ; 
    talk() : string { return "quack" ; } 
} 

class Chicken extends Animal { 
    onlyInChicken : string ; 
    talk() : string { return "cluck" ; } 
} 

但是,這似乎是一個粗糙的黑客。

是否有一種優雅的方式來要求函數參數是參數類型的(子)類的實例?

+0

雞可能像鴨子一樣走路,但他們不會像鴨子一樣說話。 –

+0

試試這個:var a:Chicken = new Chicken();這將迫使'a'是雞的類型。 – Delta

+0

@Delta將'a'的類型聲明爲'Chicken'並沒有什麼區別。 –

回答

2

我可能在這裏錯了,但我猜測可能不是。這似乎是通過設計使TypeScript語言更易於與現有JavaScript代碼進行互操作,以及支持語言的動態特性。更具體地說,由於JavaScript(以及擴展名TypeScript)實際上並不具有「類型」(在傳統意義上),所以TypeScript編譯器更關心特定實例是否遵守特定的接口,具有相同的屬性,功能等,而不是使用特定構造函數創建它。

爲了你的緣故,我希望自己錯了,但是這不會讓我感到驚訝。

+0

是的你是對的。這是一個功能不是bug。 Typescript使用靜態鴨子打字。問題不是「爲什麼我的代碼要編譯?」而且它不是「爲什麼Typescript不像Java程序員期望的那樣?」問題是:什麼是最優雅的方式來重寫我的代碼,所以它不會編譯的情況下,參數不是參數類型的實例,但編譯,否則? –

+1

您發佈的解決方案確實是最優雅的。 –

相關問題