2017-04-13 241 views
3

是否可以更改在接口中聲明的屬性的類型?我不知道如何用文字解釋這個,所以這裏是一個我試圖做的不起作用的簡單例子:TypeScript聲明合併 - 更改屬性類型

假設Movie命名空間是在第三方庫中定義的,不要控制:

declare namespace Movie { 
    interface Character { 
    doSomething(): Promise<void>; 
    friend: Character; 
    } 
} 

現在在我的應用程序中,我希望我的角色超級,與超級朋友。於是,我就做我自己的分型:

declare namespace Movie { 
    interface Character { 
    doAnExtraThing(): Promise<void>; // OK to add a new method 
    nickname: string;    // OK to add a new property 
    friend: SuperCharacter;   // NOT OK to override type with a subtype 
    } 

    interface SuperCharacter extends Character { 
    doSomethingSuper(): Promise<void>; 
    } 
} 

這可能沒有什麼工作,因爲打字稿不會讓我與SuperCharacter覆蓋friend屬性類型,即使通過定義一個SuperCharacter a Character。打字稿抱怨與此錯誤:

[ts] Subsequent variable declarations must have the same type. Variable 
'friend' must be of type 'Character', but here has type 'SuperCharacter'. 

我希望通過具有SuperCharacter延長原Character界面我不會有這個問題,但我做的。

希望這很清楚我想要達到的目標。有沒有辦法做到這一點?

回答

0

沒有理由明確指定friend可以是SuperCharacter因爲SuperCharacter已經是Character

所以,你可以完全刪除此塊:

接口字{ 朋友:SuperCharacter; }

爲了證明這一點,我們可以從界面一步之遙,並着眼於實現與才能正確編譯類:

class Character { 
    friend?: Character 

    constructor(friend?: Character) { 
    this.friend = friend 
    } 

    doSomething() {} 
} 

class SuperCharacter extends Character { 
    doSomethingSuper() {} 
} 


new Character(new Character()) 
new Character(new SuperCharacter()) 
new SuperCharacter(new Character()) 
new SuperCharacter(new SuperCharacter()) 
+0

不幸的是這不適合我的使用情況下工作。就像我在原帖中所說的那樣,我希望我的角色和超級好友一起成爲超級玩家,這意味着我應該可以做'const character = new Character()',然後'character.doSomethingSuper()'或者'character。 friend.doSomethingSuper()'。 – Merott

+0

在這種情況下,您需要實例化一個SuperCharacter以「const character = new SuperCharacter()'開始。來自子類的方法,例如'doSomethingSuper()'永遠不會出現在父類中! – fny

+0

我無法控制如何創建實例。我的問題是關於如何通過聲明合併將現有接口上的屬性類型更改爲新的兼容***類型(與子類型相同)。可以向接口添加新屬性,但似乎無法更改屬性的類型,即使新類型與原始類型兼容。 – Merott