如何改变/扩展财产的类型?

时间:2016-11-14 20:13:18

标签: typescript typescript-typings

鉴于javascript库的以下环境类型定义(我无法更改):

// a library with typings I cannot change
interface Widget {
    name: string;
}
interface Event {
    widget: Widget;
}

declare function addListener(listener: (event: Event) => void):void;
declare function showWidget(renderFn: (widget: Widget) => void): void;

这个javascript库有一个扩展模块,通过这样的方式增强event.widget(但不是一般的Widget);

interface EnhancedWidget {
    displayName: string;
}
function eventExtender(event:Event) {
    (event.widget as any).displaName = '....';
} 

现在我想用这个定义来增强Event,但是typescript抱怨

interface Event {
    widget: Widget & EnhancedWidget;
}

允许添加新属性,但不允许更改属性的类型。但这是现实中可能发生的事情。我想知道是否有办法在打字稿中表达这一点。

最后,我想使用displayName的新event.widget属性:

addListener( event => console.log(event.widget.displaName) )

但是这应该是抱怨(因为在这种情况下小部件没有得到增强):

showWidget(widget => console.log(event.displaName))

因此,像这样延长Widget 一个选项:

// does not work, because it will enhance all Widget usages and
// not just in the specific context
interface Widget {
    displayName: string;
}

1 个答案:

答案 0 :(得分:0)

如何拥有这些:

interface EnhancedWidget extends Widget {
    displayName: string;
}
interface EnhancedEvent extends Event {
    widget: EnhancedWidget;
}

然后为addListener添加另一个签名:

declare function addListener(listener: (event: EnhancedEvent) => void):void;

这仍然会失败:

addListener(event => console.log(event.widget.displayName));

使用:

  

属性'displayName'在类型'Widget'上不存在

但这会奏效:

addListener((event: EnhancedEvent) => console.log(event.widget.displayName))