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

Promise-based events.once in typed-emitter #24

Open
leumasme opened this issue Jan 16, 2022 · 2 comments
Open

Promise-based events.once in typed-emitter #24

leumasme opened this issue Jan 16, 2022 · 2 comments

Comments

@leumasme
Copy link

leumasme commented Jan 16, 2022

Does typed-emitter have support for the "once" function of the "events" inbuilt package?
nodejs/node#26078
Used like this:

import { once } from "events"
// ...
await once(emitter, "event");

This is not typed, and its not even a function on the EventEmitter - is there a clean way to type this without reimplementing the promise-based once function?
Thanks for your work on this package!

@andywer
Copy link
Owner

andywer commented Jan 16, 2022

Hey @leumasme.

We might be able to "fix it" with a global type declaration extending the existing events interface, potentially under a new entry point in typed-emitter.

Haven't tried yet, though. Would be happy to give it a try if you were to prepare a PR.

PS: I do think it is a function on the EventEmitter, a static one, though.

@martinheidegger
Copy link

This should be possible like this:

playground

import { once, EventEmitter } from "events";
import TypedEmitter from "typed-emitter";

// --- Utils
type EventsFor <T extends TypedEmitter<any>> = T extends TypedEmitter<infer EventMap> ? keyof EventMap : never
type FirstArg <FN extends (...opts: any[]) => any> = Parameters<FN>[0]
type FirstEventArg <Emitter extends TypedEmitter<any>, Event extends EventsFor<Emitter>> = Emitter extends TypedEmitter<infer EventMap> ? FirstArg<EventMap[Event]> : never;

// --- Exported by typed-emitter
type Once = <Emitter extends TypedEmitter<any>, Event extends EventsFor<Emitter>> (emitter: Emitter, event: Event) => Promise<FirstEventArg<Emitter, Event>>

// --- Example declaration 
const emitter = (new EventEmitter()) as TypedEmitter<{
    A: (foo: number) => void
    B: (foo: string) => void
}>

// --- Example usage
const res = await (once as Once)(emitter, 'A');

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

3 participants