2017-04-13 22 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