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; 

И есть модуль расширения к тому, что Java-библиотека, которая усиливает event.widget (но не Widget вообще) что-то вроде этого ;

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

Теперь я хочу, чтобы усилить Event с этим определением, но машинописный жалуется

interface Event { 
    widget: Widget & EnhancedWidget; 
} 

Добавление новых свойств допускается, но меняется тип собственности, не допускается. Но это то, что может произойти в действительности. Интересно, есть ли способ выразить это в машинописном тексте.

В конце концов, я хочу использовать новый displayName свойство event.widget:

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

Но это должен жаловаться (потому что виджет не усиливается в этом контексте):

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

Поэтому расширение Widget как это не a опция:

// 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

Дело в том, у меня нет контроля над библиотекой (первый блок кодирования) , В этой библиотеке есть множество функций 'addListener', и я не хочу переписывать все типизации для внешней библиотеки. –

+0

А, я вижу, как это работает в этом конкретном случае. Тем не менее, я должен был бы знать, использовать 'EnhancedEvent' в обратном вызове. Я ищу способ, которым завершение кода скажет мне, что 'event.widget' теперь имеет новые атрибуты. –

+0

Я не думаю, что это возможно. Использование 'EnhancedEvent' - это просто нормальный полиморфизм. Имеет смысл использовать новый тип, потому что вы действительно не меняете все экземпляры событий/виджетов, просто те, кто получил «расширенный». –

Смежные вопросы