2016-11-14 2 views
0

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; 

と拡張モジュールは、このようなものでevent.widgetを強化するライブラリが(一般的にはウィジェットではない)のjavascriptことにあります;

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

今、私は、この定義でEventを強化したいが、typescriptですが、新しいプロパティを追加する

interface Event { 
    widget: Widget & EnhancedWidget; 
} 

を文句は許可されますが、プロパティのタイプを変更することはできません。しかし、これは現実には起こり得ることです。これをタイプスクリプトで表現する方法があるのだろうかと思います。私はevent.widgetの新しいdisplayNameプロパティを使用したい終わり

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; 
} 
これらが約

答えて

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」タイプに存在しません「ウィジェット」

しかし、これは動作します:

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

ポイントは、私は、ライブラリの制御(第1の符号化ブロック)を持っていない、あります。そのライブラリにはたくさんの 'addListener'のような関数があり、私は外部ライブラリの型を書き直したくありません。 –

+0

ああ、私はこの特定の場合にどのように動作するかを見ています。しかし、私はコールバックで 'EnhancedEvent'を使うことを知る必要があります。私は、コード補完によって 'event.widget'に新しい属性が追加されたことを私に伝える方法を探しています。 –

+0

私はそれが可能だとは思わない。 'EnhancedEvent'を使うことはちょうど普通の多態性です。実際には、イベント/ウィジェットのすべてのインスタンスを変更しているわけではないので、新しいタイプを使用することは理にかなっています。 –

関連する問題