надо не
this
типизировать, а имя метода вместо
string
делать
keyof this
.
abstract class BaseComp {
abstract listeners: readonly (keyof this)[];
attachListeners() {
this.listeners.forEach(name => {
const method = this[name];
if(typeof method == 'function') {
this[name] = method.bind(this);
// attach
}
})
}
onError() {}
}
class Comp extends BaseComp {
listeners = ["onClick", "onError"] as const;
onClick(){}
}
правда так оно позволит вместо имени метода имя проперти подсунуть. а с фильтром на условном типе
отсюда придётся тип класса потомка передавать явно (выводить оно его не хочет). но зато кроме имён методов ничего передать будет нельзя:
type FunctionPropertyNames<T> = { [K in keyof T]: T[K] extends Function ? K : never }[keyof T];
function attachListeners<T extends BaseComp2>(component:T, listeners: FunctionPropertyNames<T>[]) {
listeners.forEach(name => {
const method = component[name];
if(typeof method == 'function') {
component[name] = method.bind(component);
// attach
}
})
}
abstract class BaseComp2 {
onError() {}
}
class Comp2 extends BaseComp2 {
constructor() {
super();
attachListeners<Comp2>(this,["onCLick", "onError"]);
}
onCLick(){}
}