Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add type annotations to events of WebSocketServer/Client #30

Open
cdrini opened this issue Oct 3, 2021 · 3 comments
Open

Add type annotations to events of WebSocketServer/Client #30

cdrini opened this issue Oct 3, 2021 · 3 comments

Comments

@cdrini
Copy link

cdrini commented Oct 3, 2021

Being able to having things like connection auto-complete would be very helpful. Eg.

image

image

@cdrini
Copy link
Author

cdrini commented Oct 3, 2021

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 :/

@SaaS25 SaaS25 mentioned this issue Oct 6, 2021
@Danielduel
Copy link
Contributor

// copy from #31
Hmm... I did that in #34 but I was only modifying "on" and "emit" since I rarely use other API parts.
I think I can add more typings 👀

//
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.

@Danielduel
Copy link
Contributor

Waiting for update in std library, hopefully they will approve my changes :)
denoland/deno_std#2111

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants