I'm trying to migrate my project from a JavaScript to TypeScript, and I have a problem with migrating the class for handling events.
To avoid double describing options for an add/remove event listener, we use a wrapper like this:
constructor() {
this.windowResizeHandler = new MyEventHandler(
target: window,
event: 'resize',
handler: e => this.handleResize_(e),
options: {passive: true, capturing: true},
);
}
connectedCallback() {
this.windowResizeHandler.add();
}
disconnectedCallback() {
this.windowResizeHandler.remove();
}
Now I don't know how to write this in TypeScript without losing information about events typing. For example:
document.createElement('button').addEventListener('click', e => {
// Here e is MouseEvent.
});
But if I write my wrapper like:
interface EventHandlerParams {
readonly target: EventTarget;
readonly event: Event;
readonly listener: (e: Event) => void;
readonly params: AddEventListenerOptions;
}
export class EventHandler {
public constructor(params: EventHandlerParams) {}
}
Then I lose the typings:
new MyEventHandler(
target: document.createElement('button'),
event: 'click',
handler: e => { /* Here e is just Event not MouseEvent */ },
options: {passive: true, capturing: true},
);
Is there any options for me to use event typings from lib.dom.d.ts here?
I've tried something like this:
interface Mapping {
[Window]: WindowEventMap;
[HTMLElement]: HTMLElementEventMap;
}
interface EventHandlerParams<TTarget extends keyof Mapping,
TEventName extends keyof Mapping[TTarget],
TEvent extends Mapping[TTarget][TEventName]> {
readonly event: TEventName;
readonly listener: (event: TEvent) => void;
readonly params?: AddEventListenerOptions;
readonly target: TTarget;
}
export class EventHandler<TTarget extends keyof Mapping,
TEventName extends keyof Mapping[TTarget],
TEvent extends Mapping[TTarget][TEventName]> {
public constructor(params: EventHandlerParams<TTarget, TEventName, TEvent>) {}
}
But I can't use this, because types can not be interface properties and there is no any other options to provide constraint for TTarget.