#наследование #typescript #множественное_наследование #mixins #прототипное_наследование
Есть класс и функция-конструктор. Делается попытка реализовать класс, являющийся чем-то типа потомка обоих. Точнее, методы из прототипа функции-конструктора копируются в прототип класса-потомка, унаследованный от класса. Да, я понимаю, что это не полноценное наследование, но для решения задачи этого хватает. Проблема в другом. Как заставить тайпскрипт воспринимать копируемые методы? class First { someMethod() { console.log('someMethod from First'); } } function Second() { console.log('Second'); } Second.prototype.doSmth = function () { console.log('doSmth from Second'); } interface IBoth { someMethod() doSmth() } class Both extends First /* implements IBoth */ { constructor() { console.log('constructor of Both'); super(); Second.call(this); } } for (let key in Second.prototype) { Both.prototype[key] = Second.prototype[key]; } На самом деле, надо обеспечить видимость методов ещё на уровень дальше class Final extends Both { doIt() { this.someMethod(); //this.doSmth(); // Надо заставить видеть метод тут (this as any as IBoth).doSmth(); // Компилируется, но это ужас } } если при этом методы не будут видны из самого Both, то это годится. Вот что я уже пробовал: При попытке написать class Both extends First implements IBoth { возникает ошибка, что я не реализую методы интерфейса. При переименовании Both в _Both и использовании var Both = _Both as typeof _Both; всё остаётся как было, что логично, поскольку тут никак не используется First. При переименовании Both в _Both и использовании var Both = _Both as typeof IBoth; говорит, что не может найти имя IBoth. Пробовал ещё несколько вариантов, но они совсем бредовые. Что ещё можно сделать? Попробовать можно тут: http://www.typescriptlang.org/Playground Полный код для проверки Запустить (код из правой панели) после добавления строки: (new Final).doIt(); Вывод при запуске при раскомментированной строке this.doSmth(); constructor of Both Second someMethod from First doSmth from Second doSmth from Second PS: Этот вопрос на английском.
Ответы
Ответ 1
Интерфейс вообще не нужен, нужно просто объявить прототипное поле с нужным типом: doSmth: () => void Она видима как свойство, а не как метод, но это непринципиально. Полный код: class First { someMethod() { console.log('someMethod from First'); } } function Second() { console.log('Second'); } Second.prototype.doSmth = function () { console.log('doSmth from Second'); } class Both extends First { constructor() { console.log('constructor of Both'); super(); Second.call(this); } doSmth: () => void } for (let key in Second.prototype) { Both.prototype[key] = Second.prototype[key]; } class Final extends Both { doIt() { this.someMethod(); this.doSmth(); //Both.prototype.doSmth(); // ok //Final.prototype.doSmth(); // ok } } PS: Надо было гуглить не всяческие варианты с наследованием, а typescript class prototype variable - сразу нашёл подходящий вариант.
Комментариев нет:
Отправить комментарий