2014-10-30 3 views
1

Я хочу построить функцию, которая принимает любой объект и возвращает этот объект с несколькими добавленными свойствами. что-то вроде:расширение интерфейса с generic в машинописных текстах

//this code doesn't work 
     function addProperties<T>(object: T): IPropertiesToAdd<T> {/*implmentions code*/}; 

     interface IPropertiesToAdd<T> extend T{ 
      on(): void; 
      off(): void; 
     } 

//usage example 
var str = new String('Hello') 
addProperties(str) 
str.charAt(3) 
str.on() 

для кода выше машинопись компилятора возвращает ошибку, что интерфейс может только добавить класс или интерфейс, как я могу выразить это в машинописи.

ответ

8

Интерфейс IPropertiesToAdd определяет переменную типа T, которая используется для расширения интерфейса с именем T. Это невозможно. Нельзя ссылаться на интерфейс с использованием имени переменной; он должен иметь фиксированное имя, например. Evnt:

interface Evnt<T> { 
    name: T; 
} 

interface IPropertiesToAdd<T> extends Evnt<T> { 
    on(): void; 
    off(): void; 
} 

Я не уверен, чего вы пытаетесь достичь в своем случае. Я продлевал пример немного, поэтому он компилирует:

function addProperties<T>(object: Evnt<T>): IPropertiesToAdd<T> { 
    /* minimum implementation to comply with interface*/ 
    var ext:any = {}; 
    ext.name = object.name 
    ext.on = function() {}; 
    ext.off = function() {}; 
    return ext; 
}; 

interface Evnt<T> { 
    name: T; 
} 

interface IPropertiesToAdd<T> extends Evnt<T> { 
    on(): void; 
    off(): void; 
} 

//usage example 
var str = {name: 'Hello'} 
var evnt = addProperties(str) 
evnt.charAt(3); // error because evnt is not of type 
       // `string` but `IPropertiesToAdd<string>` 
evnt.on() 
+0

спасибо за ваше время, с небольшим изменением архитектуры, ваш ответ действительно помог. – user2692945

3

Вы можете создать новый type alias, который позволит вашему объекту наследовать свойства другого типа объекта. Я нашел этот бит кода here.

type IPropertiesToAdd<T extends {}> = T & { // '{}' can be replaced with 'any' 
    on(): void 
    off(): void 
}; 

interface ISomething { 
    someValue: number 
} 

var extendedType: IPropertiesToAdd<ISomething> = { 
    on(): void { 
     console.log("switched on"); 
    }, 
    off(): void { 
     console.log("switched off"); 
    }, 
    someValue: 1234, 
}; 

Я тестировал это, и кажется, что «T» может быть интерфейсом, классом и типом массива. Я не мог заставить профсоюзные типы работать.

Это работает только с анонимными объектами, оно не может использоваться для фактических целей наследования.

Надеюсь, это поможет.

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