Open cdrini opened 2 years ago
Looking at VS code's internals, they do something like this for HTML:
interface DocumentEventMap extends GlobalEventHandlersEventMap, DocumentAndElementEventHandlersEventMap {
"fullscreenchange": Event;
"fullscreenerror": Event;
"pointerlockchange": Event;
"pointerlockerror": Event;
"readystatechange": Event;
"visibilitychange": Event;
}
/** The HTMLDocument property of Window objects is an alias that browsers expose for the Document interface object. */
interface HTMLDocument extends Document {
addEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: HTMLDocument, ev: DocumentEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void;
addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void;
removeEventListener<K extends keyof DocumentEventMap>(type: K, listener: (this: HTMLDocument, ev: DocumentEventMap[K]) => any, options?: boolean | EventListenerOptions): void;
removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void;
}
For this class, which extends Deno's EventEmitter
, something like this seems to do the trick!
type WebSockerServerEventMap = {
'connection': (ws: WebSocketClient) => any,
'error': (error: Error) => any,
}
class WSServer extends EventEmitter {
on<K extends keyof WSServerEventMap>(eventName: K, listener: WSServerEventMap[K]): this;
on(eventName: string | symbol, listener: GenericFunction | WrappedFunction): this {
return super.on(eventName, listener);
}
once<K extends keyof WSServerEventMap>(eventName: K, listener: WSServerEventMap[K]): this;
once(eventName: string | symbol, listener: GenericFunction): this {
return super.once(eventName, listener);
}
addListener<K extends keyof WSServerEventMap>(eventName: K, listener: WSServerEventMap[K]): this;
addListener(eventName: string | symbol, listener: GenericFunction | WrappedFunction): this {
return super.addListener(eventName, listener);
}
}
Not a huge fan of having to wrap the super
method; I feel like there should be a type-only way to do this? But can't seem to find it :/
// copy from #31 Hmm... I did that in https://github.com/ryo-ma/deno-websocket/pull/34 but I was only modifying "on" and "emit" since I rarely use other API parts. I think I can add more typings :eyes:
// Actually I think about checking out why the EventEmitter from std library doesn't have (not sure atm) an exported EventEmitter set up in the way that allows passing event map, because I feel this is weird the std module of typescript runtime doesn't do that as default.
Waiting for update in std library, hopefully they will approve my changes :) https://github.com/denoland/deno_std/pull/2111
Being able to having things like
connection
auto-complete would be very helpful. Eg.