Skip to content

Instantly share code, notes, and snippets.

@rbuckton
Created July 31, 2019 04:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rbuckton/2b89b7029be5d7079f5da84cbb16e84d to your computer and use it in GitHub Desktop.
Save rbuckton/2b89b7029be5d7079f5da84cbb16e84d to your computer and use it in GitHub Desktop.
export {};
/** A non-existent symbol used to define the types of events defined on an object */
declare const kEvents: unique symbol;
/** Gets the events defined on an object. */
type Events<T> = T extends { readonly [kEvents]: infer Events } ? Events : {};
/** Get the names of events defined on an object. */
type EventNames<T> = keyof Events<T>;
/** Gets the listener for an event defined on an object. */
type EventListener<T, E extends EventNames<T>> =
Events<T>[E] extends ((...args: infer A) => any)
? (this: T, ...args: A) => void
: never;
/** Gets the arguments for an event defined on an object */
type EventArgs<T, E extends EventNames<T>> =
Parameters<EventListener<T, E>>;
declare class EventEmitter {
readonly [kEvents]: {};
on<E extends EventNames<this>>(event: E, listener: EventListener<this, E>): this;
on(event: string | symbol, listener: Function): this;
emit<E extends EventNames<this>>(event: E, ...args: EventArgs<this, E>): boolean;
emit(event: string | symbol, ...args: unknown[]): boolean;
}
declare class SuperClass extends EventEmitter {
readonly [kEvents]: {
"error": (error: Error) => void;
};
}
declare class SubClass extends SuperClass {
readonly [kEvents]: Events<SuperClass> & {
"end": () => void;
};
}
declare const x: SubClass;
x.on("error", error => {});
x.on("end", () => {});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment