Задача, мягко говоря, так себе. Много подводных камней и тд. Однако можно реализовать с оговорками. Методы onClick, onInput и тд., описаны в специальном интерфейсе, его можно имплементировать, или как-то использовать. Но, во первых, тебе придется играться с этими наименованиями, чтоб как-то избежать переопределения этих свойств из разных объектов. Во вторых, это делать плохо и ненадежно. Для всего этого придумали addEventListener. По этому, можно посмотреть какой у него интерфейс, и на основе него построить свои классы так, чтоб можно было создавать какие угодно классы, с нужными ивентами. Но в них не должно быть ничего лишнего, кроме ивентов.
TypeScript Playground
interface Object {
entries<T>(o: { [s: string]: T } | ArrayLike<T>): [string, T][];
}
type TEventType = keyof HTMLElementEventMap;
type TEventCallback = (this: HTMLElement, ev: HTMLElementEventMap[TEventType]) => any;
type IListener = {
[key in TEventType]?: TEventCallback;
};
class ListenerA implements IListener {
public click() {
console.log("ListenerA.click");
}
public mousemove() {
console.log("ListenerA.mousemove");
}
}
class ListenerB implements IListener {
public click() {
console.log("ListenerB.click");
}
}
class DocumentListener {
constructor(...components: IListener[]) {
for (const component of components) {
const proto = Reflect.getPrototypeOf(component);
const events = Reflect.ownKeys(proto)
.filter(key => key !== "contructor") as (keyof IListener)[];
for (const event of events) {
const callback = component[event];
if (callback !== undefined) {
document.body.addEventListener(event, callback);
}
}
}
}
}
const dl = new DocumentListener(new ListenerA(), new ListenerB());
P.S. Крайне не рекомендую заниматься такой фигней. Есть более удобные способы навешивания событий, при том понятные, легко-поддерживаемые.
type TEventType = keyof HTMLElementEventMap;
type TEventCallback = (this: HTMLElement, ev: HTMLElementEventMap[TEventType]) => any;
type IEvent = {
event: TEventType;
callback: TEventCallback;
}
interface IListener {
events: IEvent[];
on(event: TEventType, callback: TEventCallback): any;
};
class Listener implements IListener {
events: IEvent[] = [];
on(event: TEventType, callback: TEventCallback) {
this.events.push({event, callback});
}
}
class DocumentListener {
constructor(...components: IListener[]) {
for (const component of components) {
for (const { event, callback } of component.events) {
document.body.addEventListener(event, callback);
}
}
}
}
const l1 = new Listener();
l1.on("click", () => {
console.log("l1.click");
});
const l2 = new Listener();
l2.on("click", () => {
console.log("l2.click");
});
const dl = new DocumentListener(l1, l2);