// Modified from // https://github.com/bterlson/strict-event-emitter-types/blob/96b30cae8d128c166b575c4c9a524c997ab4f040/src/index.ts // for better JSDoc support (as of TS 2.8, JSDoc does not support method overrides // in JS, so not possible to implement the original OverriddenMethods). // Returns any keys of TRecord with the type of TMatch export type MatchingKeys< TRecord, TMatch, K extends keyof TRecord = keyof TRecord > = K extends (TRecord[K] extends TMatch ? K : never) ? K : never; // Returns any property keys of Record with a void type export type VoidKeys = MatchingKeys; // TODO: Stash under a symbol key once TS compiler bug is fixed export interface TypeRecord { ' _emitterType'?: T, ' _eventsType'?: U, ' _emitType'?: V } // EventEmitter method overrides, modified so no overloaded methods. export type OverriddenMethods< TEventRecord, TEmitRecord = TEventRecord > = { on

(event: P, listener: TEventRecord[P] extends void ? () => void : (m: TEventRecord[P], ...args: any[]) => void): void addListener

(event: P, listener: TEventRecord[P] extends void ? () => void : (m: TEventRecord[P], ...args: any[]) => void): void addEventListener

(event: P, listener: TEventRecord[P] extends void ? () => void : (m: TEventRecord[P], ...args: any[]) => void): void removeListener

(event: P, listener: Function): any; once

(event: P, listener: TEventRecord[P] extends void ? () => void : (m: TEventRecord[P], ...args: any[]) => void): void // TODO(bckenny): breaking change from original. A void TEmitRecord[P] meant // no second parameter, but now a second one is always required and must // extend `void` (e.g. `undefined`). emit

(event: P, request: TEmitRecord[P]): void; } export type OverriddenKeys = keyof OverriddenMethods export type StrictEventEmitter< TEmitterType, TEventRecord, TEmitRecord = TEventRecord, UnneededMethods extends Exclude = Exclude, NeededMethods extends Exclude = Exclude > = // Store the type parameters we've instantiated with so we can refer to them later TypeRecord & // Pick all the methods on the original type we aren't going to override Pick> & // Finally, pick the needed overrides (taking care not to add an override for a method // that doesn't exist) Pick, NeededMethods>; export default StrictEventEmitter; export type NoUndefined = T extends undefined ? never : T; export type StrictBroadcast< TEmitter extends TypeRecord, TEmitRecord extends NoUndefined = NoUndefined, VK extends VoidKeys = VoidKeys, NVK extends Exclude = Exclude > = { (event: E, request: TEmitRecord[E]): void; (event: E): void; }