diff --git a/types/imap/index.d.ts b/types/imap/index.d.ts index 813b7b57124bbe..b8d548381519bc 100644 --- a/types/imap/index.d.ts +++ b/types/imap/index.d.ts @@ -267,6 +267,18 @@ declare namespace Connection { declare class Connection extends EventEmitter implements Connection.MessageFunctions { constructor(config: Connection.Config); + // from NodeJS.EventEmitter + addListener(event: string, listener: Function): this; + on(event: string, listener: Function): this; + once(event: string, listener: Function): this; + removeListener(event: string, listener: Function): this; + removeAllListeners(event?: string): this; + setMaxListeners(n: number): this; + getMaxListeners(): number; + listeners(event: string): Function[]; + emit(event: string, ...args: any[]): boolean; + listenerCount(type: string): number; + // from MessageFunctions /** Searches the currently open mailbox for messages using given criteria. criteria is a list describing what you want to find. For criteria types that require arguments, use an array instead of just the string criteria type name (e.g. ['FROM', 'foo@bar.com']). Prefix criteria types with an "!" to negate. */ search(criteria: any[], callback: (error: Error, uids: number[]) => void): void; diff --git a/types/jake/index.d.ts b/types/jake/index.d.ts index e4437473089e2c..7a0e20bd77f730 100644 --- a/types/jake/index.d.ts +++ b/types/jake/index.d.ts @@ -241,6 +241,16 @@ declare global { */ reenable(): void; + addListener(event: string, listener: Function): this; + on(event: string, listener: Function): this; + once(event: string, listener: Function): this; + removeListener(event: string, listener: Function): this; + removeAllListeners(event?: string): this; + setMaxListeners(n: number): this; + getMaxListeners(): number; + listeners(event: string): Function[]; + emit(event: string, ...args: any[]): boolean; + listenerCount(type: string): number; complete(value?: any): void; value: any; diff --git a/types/newman/newman-tests.ts b/types/newman/newman-tests.ts index 92f03da5abcc00..88b8df8eac1efd 100644 --- a/types/newman/newman-tests.ts +++ b/types/newman/newman-tests.ts @@ -23,7 +23,7 @@ const workingDir = "path/to/working/directory"; const insecureFileRead = true; const requestAgent = new http.Agent(); -// $ExpectType EventEmitter<{}> +// $ExpectType EventEmitter run( { collection, diff --git a/types/node-red/node-red-tests.ts b/types/node-red/node-red-tests.ts index 4b09b211136b28..0d359e53d5e242 100644 --- a/types/node-red/node-red-tests.ts +++ b/types/node-red/node-red-tests.ts @@ -23,7 +23,7 @@ async function REDTests() { // $ExpectType Util RED.util; - // $ExpectType EventEmitter<{}> + // $ExpectType EventEmitter RED.events; // $ExpectType Hooks diff --git a/types/node/events.d.ts b/types/node/events.d.ts index cc4b908bd8a68b..63b9433635bdf9 100644 --- a/types/node/events.d.ts +++ b/types/node/events.d.ts @@ -34,7 +34,6 @@ * ``` * @see [source](https://github.com/nodejs/node/blob/v22.x/lib/events.js) */ - declare module "events" { import { AsyncResource, AsyncResourceOptions } from "node:async_hooks"; // NOTE: This class is in the docs but is **not actually exported** by Node. @@ -100,27 +99,23 @@ declare module "events" { */ lowWaterMark?: number | undefined; } - interface EventEmitter = {}> extends NodeJS.EventEmitter {} - type EventMap = Record; - type Args, EventName> = EventName extends keyof Events ? ( - | Events[EventName] - | (EventName extends keyof EventEmitter.EventEmitterBuiltInEventMap - ? EventEmitter.EventEmitterBuiltInEventMap[EventName] - : never) - ) - : (EventName extends keyof EventEmitter.EventEmitterBuiltInEventMap - ? EventEmitter.EventEmitterBuiltInEventMap[EventName] - : any[]); - type EventNames> = {} extends Events ? (string | symbol) - : (keyof Events | keyof EventEmitter.EventEmitterBuiltInEventMap); - type Listener, EventName> = EventName extends keyof Events ? - | ((...args: Events[EventName]) => void) - | (EventName extends keyof EventEmitter.EventEmitterBuiltInEventMap - ? (...args: EventEmitter.EventEmitterBuiltInEventMap[EventName]) => void - : never) - : (EventName extends keyof EventEmitter.EventEmitterBuiltInEventMap - ? (...args: EventEmitter.EventEmitterBuiltInEventMap[EventName]) => void - : (...args: any[]) => void); + interface EventEmitter = DefaultEventMap> extends NodeJS.EventEmitter {} + type EventMap = Record | DefaultEventMap; + type DefaultEventMap = [never]; + type AnyRest = [...args: any[]]; + type Args = T extends DefaultEventMap ? AnyRest : ( + K extends keyof T ? T[K] : never + ); + type Key = T extends DefaultEventMap ? string | symbol : K | keyof T; + type Key2 = T extends DefaultEventMap ? string | symbol : K & keyof T; + type Listener = T extends DefaultEventMap ? F : ( + K extends keyof T ? ( + T[K] extends unknown[] ? (...args: T[K]) => void : never + ) + : never + ); + type Listener1 = Listener void>; + type Listener2 = Listener; /** * The `EventEmitter` class is defined and exposed by the `node:events` module: @@ -135,20 +130,10 @@ declare module "events" { * It supports the following option: * @since v0.1.26 */ - class EventEmitter = {}> { + class EventEmitter = DefaultEventMap> { constructor(options?: EventEmitterOptions); - // This "property" is used to brand a specific instance of the EventEmitter class with its Event map, which is needed - // in order to infer the map if we have a chain like `class A extends EventEmitter<{}>` (or many levels deep) - // It is also marked as possibly undefined in order to allow something like `const t: NodeJS.EventEmitter<{}> = { };` - readonly #internalTypeOnlyBrand?: Events; - - [EventEmitter.captureRejectionSymbol]?>( - error: Error, - event: EventName, - ...args: Args - ): void; - [EventEmitter.captureRejectionSymbol]?(error: Error, event: string | symbol, ...args: any[]): void; + [EventEmitter.captureRejectionSymbol]?(error: Error, event: Key, ...args: Args): void; /** * Creates a `Promise` that is fulfilled when the `EventEmitter` emits the given @@ -229,11 +214,6 @@ declare module "events" { * ``` * @since v11.13.0, v10.16.0 */ - static once, EventName extends EventNames>( - emitter: EventEmitter, - eventName: EventName, - options?: StaticEventEmitterOptions, - ): Promise>; static once( emitter: NodeJS.EventEmitter, eventName: string | symbol, @@ -320,11 +300,6 @@ declare module "events" { * @since v13.6.0, v12.16.0 * @return An `AsyncIterator` that iterates `eventName` events emitted by the `emitter` */ - static on, EventName extends EventNames>( - emitter: EventEmitter, - eventName: EventName, - options?: StaticEventEmitterIteratorOptions, - ): NodeJS.AsyncIterator>; static on( emitter: NodeJS.EventEmitter, eventName: string | symbol, @@ -335,27 +310,6 @@ declare module "events" { eventName: string, options?: StaticEventEmitterIteratorOptions, ): NodeJS.AsyncIterator; - /** - * A class method that returns the number of listeners for the given `eventName` registered on the given `emitter`. - * - * ```js - * import { EventEmitter, listenerCount } from 'node:events'; - * - * const myEmitter = new EventEmitter(); - * myEmitter.on('event', () => {}); - * myEmitter.on('event', () => {}); - * console.log(listenerCount(myEmitter, 'event')); - * // Prints: 2 - * ``` - * @since v0.9.12 - * @deprecated Since v3.2.0 - Use `listenerCount` instead. - * @param emitter The emitter to query - * @param eventName The event name - */ - static listenerCount, EventName extends EventNames>( - emitter: EventEmitter, - eventName: EventName, - ): number; /** * A class method that returns the number of listeners for the given `eventName` registered on the given `emitter`. * @@ -401,14 +355,7 @@ declare module "events" { * ``` * @since v15.2.0, v14.17.0 */ - static getEventListeners, EventName extends EventNames>( - emitter: EventEmitter, - name: EventName, - ): Array>; - static getEventListeners( - emitter: EventTarget | NodeJS.EventEmitter, - name: string | symbol, - ): Function[]; + static getEventListeners(emitter: EventTarget | NodeJS.EventEmitter, name: string | symbol): Function[]; /** * Returns the currently set max amount of listeners. * @@ -638,37 +585,16 @@ declare module "events" { */ readonly asyncResource: EventEmitterReferencingAsyncResource; } - - export interface EventEmitterBuiltInEventMap { - newListener: [eventName: string | symbol, listener: Function]; - removeListener: [eventName: string | symbol, listener: Function]; - } } global { namespace NodeJS { - interface EventEmitter = {}> { - [EventEmitter.captureRejectionSymbol]?>( - error: Error, - event: EventName, - ...args: Args - ): void; - [EventEmitter.captureRejectionSymbol]?( - error: Error, - event: EventName, - ...args: Args - ): void; + interface EventEmitter = DefaultEventMap> { + [EventEmitter.captureRejectionSymbol]?(error: Error, event: Key, ...args: Args): void; /** * Alias for `emitter.on(eventName, listener)`. * @since v0.1.26 */ - addListener>( - eventName: EventName, - listener: Listener, - ): this; - addListener( - eventName: EventName, - listener: Listener, - ): this; + addListener(eventName: Key, listener: Listener1): this; /** * Adds the `listener` function to the end of the listeners array for the event * named `eventName`. No checks are made to see if the `listener` has already @@ -700,14 +626,7 @@ declare module "events" { * @param eventName The name of the event. * @param listener The callback function */ - on>( - eventName: EventName, - listener: Listener, - ): this; - on( - eventName: EventName, - listener: Listener, - ): this; + on(eventName: Key, listener: Listener1): this; /** * Adds a **one-time** `listener` function for the event named `eventName`. The * next time `eventName` is triggered, this listener is removed and then invoked. @@ -737,14 +656,7 @@ declare module "events" { * @param eventName The name of the event. * @param listener The callback function */ - once>( - eventName: EventName, - listener: Listener, - ): this; - once( - eventName: EventName, - listener: Listener, - ): this; + once(eventName: Key, listener: Listener1): this; /** * Removes the specified `listener` from the listener array for the event named `eventName`. * @@ -827,26 +739,12 @@ declare module "events" { * Returns a reference to the `EventEmitter`, so that calls can be chained. * @since v0.1.26 */ - removeListener>( - eventName: EventName, - listener: Listener, - ): this; - removeListener( - eventName: EventName, - listener: Listener, - ): this; + removeListener(eventName: Key, listener: Listener1): this; /** * Alias for `emitter.removeListener()`. * @since v10.0.0 */ - off>( - eventName: EventName, - listener: Listener, - ): this; - off( - eventName: EventName, - listener: Listener, - ): this; + off(eventName: Key, listener: Listener1): this; /** * Removes all listeners, or those of the specified `eventName`. * @@ -857,10 +755,7 @@ declare module "events" { * Returns a reference to the `EventEmitter`, so that calls can be chained. * @since v0.1.26 */ - /* eslint-disable @definitelytyped/no-unnecessary-generics */ - removeAllListeners>(eventName: EventName): this; - removeAllListeners(eventName?: EventName): this; - /* eslint-enable @definitelytyped/no-unnecessary-generics */ + removeAllListeners(eventName?: Key): this; /** * By default `EventEmitter`s will print a warning if more than `10` listeners are * added for a particular event. This is a useful default that helps finding @@ -889,12 +784,7 @@ declare module "events" { * ``` * @since v0.1.26 */ - listeners>( - eventName: EventName, - ): Array>; - listeners( - eventName: EventName, - ): Array>; + listeners(eventName: Key): Array>; /** * Returns a copy of the array of listeners for the event named `eventName`, * including any wrappers (such as those created by `.once()`). @@ -925,12 +815,7 @@ declare module "events" { * ``` * @since v9.4.0 */ - rawListeners>( - eventName: EventName, - ): Array>; - rawListeners( - eventName: EventName, - ): Array>; + rawListeners(eventName: Key): Array>; /** * Synchronously calls each of the listeners registered for the event named `eventName`, in the order they were registered, passing the supplied arguments * to each. @@ -971,14 +856,7 @@ declare module "events" { * ``` * @since v0.1.26 */ - emit>( - eventName: EventName, - ...args: Args - ): boolean; - emit( - eventName: EventName, - ...args: Args - ): boolean; + emit(eventName: Key, ...args: Args): boolean; /** * Returns the number of listeners listening for the event named `eventName`. * If `listener` is provided, it will return how many times the listener is found @@ -987,14 +865,7 @@ declare module "events" { * @param eventName The name of the event being listened for * @param listener The event handler function */ - listenerCount>( - eventName: EventName, - listener?: Listener, - ): number; - listenerCount( - eventName: EventName, - listener?: Listener, - ): number; + listenerCount(eventName: Key, listener?: Listener2): number; /** * Adds the `listener` function to the _beginning_ of the listeners array for the * event named `eventName`. No checks are made to see if the `listener` has @@ -1012,14 +883,7 @@ declare module "events" { * @param eventName The name of the event. * @param listener The callback function */ - prependListener>( - eventName: EventName, - listener: Listener, - ): this; - prependListener( - eventName: EventName, - listener: Listener, - ): this; + prependListener(eventName: Key, listener: Listener1): this; /** * Adds a **one-time**`listener` function for the event named `eventName` to the _beginning_ of the listeners array. The next time `eventName` is triggered, this * listener is removed, and then invoked. @@ -1035,14 +899,7 @@ declare module "events" { * @param eventName The name of the event. * @param listener The callback function */ - prependOnceListener>( - eventName: EventName, - listener: Listener, - ): this; - prependOnceListener( - eventName: EventName, - listener: Listener, - ): this; + prependOnceListener(eventName: Key, listener: Listener1): this; /** * Returns an array listing the events for which the emitter has registered * listeners. The values in the array are strings or `Symbol`s. @@ -1062,7 +919,7 @@ declare module "events" { * ``` * @since v6.0.0 */ - eventNames(): Array<(string | symbol)> & Array>; + eventNames(): Array<(string | symbol) & Key2>; } } } diff --git a/types/node/test/events.ts b/types/node/test/events.ts index ee3c21065b95e0..5ff88c63a06af5 100644 --- a/types/node/test/events.ts +++ b/types/node/test/events.ts @@ -31,7 +31,7 @@ declare const any: any; result = emitter.getMaxListeners(); result = emitter.listenerCount(event); - const handler = () => {}; + const handler: Function = () => {}; result = emitter.listenerCount(event, handler); } @@ -141,7 +141,7 @@ async function testEventTarget() { captureRejectionSymbol2 = events.captureRejectionSymbol; const emitter = new events.EventEmitter(); - emitter[events.captureRejectionSymbol] = (err: Error, name: string | symbol, ...args: any[]) => {}; + emitter[events.captureRejectionSymbol] = (err: Error, name: string, ...args: any[]) => {}; } { @@ -193,16 +193,16 @@ async function testEventTarget() { { class MyEmitter extends events.EventEmitter { - addListener(event: string | symbol, listener: () => void): this { + addListener(event: string, listener: () => void): this { return this; } - listeners(event: string | symbol): Array<() => void> { + listeners(event: string): Array<() => void> { return []; } - emit(event: string | symbol, ...args: any[]): boolean { + emit(event: string, ...args: any[]): boolean { return true; } - listenerCount(type: string | symbol): number { + listenerCount(type: string): number { return 0; } } diff --git a/types/node/test/events_generic.ts b/types/node/test/events_generic.ts index b8cb5f068da65f..ebc342451c75bc 100644 --- a/types/node/test/events_generic.ts +++ b/types/node/test/events_generic.ts @@ -110,17 +110,13 @@ declare const event5: "event5"; } { - let result1: Promise; - let result2: Promise; - let result3: Promise; - let result4: Promise; - let result5: Promise; - - result1 = events.once(emitter, event1); - result2 = events.once(emitter, event2); - result3 = events.once(emitter, event3); - result4 = events.once(emitter, event4); - result5 = events.once(emitter, event5); + let result: Promise; + + result = events.once(emitter, event1); + result = events.once(emitter, event2); + result = events.once(emitter, event3); + result = events.once(emitter, event4); + result = events.once(emitter, event5); emitter.emit("event1", "hello", 42); emitter.emit("event2", true); @@ -150,7 +146,7 @@ declare const event5: "event5"; } { - let result: Array; + let result: Array; result = emitter.eventNames(); } @@ -161,12 +157,12 @@ declare const event5: "event5"; ) : never; - function on1(event: K, listener: Listener): void { + function on1(event: K, listener: Listener): void { emitter.on(event, listener); } // eslint-disable-next-line @definitelytyped/no-unnecessary-generics - function on2(...args: Parameters>): void { + function on2(...args: Parameters>): void { emitter.on(...args); } @@ -208,6 +204,7 @@ declare const event5: "event5"; emitter.emit("abc", "hello", 123); // @ts-expect-error emitter.emit("abc", 123, false); + // @ts-expect-error emitter.emit("def", "hello", 123); } @@ -229,6 +226,7 @@ declare const event5: "event5"; emitter.emit(s1, "hello", 123); // @ts-expect-error emitter.emit(s1, 123, false); + // @ts-expect-error emitter.emit(s2, "hello", 123); } @@ -246,71 +244,6 @@ declare const event5: "event5"; emitter.emit(789, 123, false); // @ts-expect-error emitter.emit(s1, "hello", false); - emitter.emit(s2, "hello", false); -} - -{ - const promise1: Promise<[string, number]> = events.once(new events.EventEmitter(), "event1"); - const promise2: Promise<[boolean]> = events.once(new events.EventEmitter(), "event2"); - const promise3: Promise<[]> = events.once(new events.EventEmitter(), "event3"); - const promise4: Promise = events.once(new events.EventEmitter(), "event4"); - const promise5: Promise = events.once(new events.EventEmitter(), "event5"); - // @ts-expect-error - const promise6: Promise<[string, string]> = events.once(new events.EventEmitter(), "event1"); - const promise7: Promise = events.once(new events.EventEmitter(), "event"); - - const iterable1: NodeJS.AsyncIterator<[string, number]> = events.on(new events.EventEmitter(), "event1"); - const iterable2: NodeJS.AsyncIterator<[boolean]> = events.on(new events.EventEmitter(), "event2"); - const iterable3: NodeJS.AsyncIterator<[]> = events.on(new events.EventEmitter(), "event3"); - const iterable4: NodeJS.AsyncIterator = events.on(new events.EventEmitter(), "event4"); - const iterable5: NodeJS.AsyncIterator = events.on(new events.EventEmitter(), "event5"); // @ts-expect-error - const iterable6: NodeJS.AsyncIterator<[string, string]> = events.on(new events.EventEmitter(), "event1"); - const iterable7: NodeJS.AsyncIterator = events.on(new events.EventEmitter(), "event"); -} - -{ - function acceptsEventEmitterInterface(eventEmitter: NodeJS.EventEmitter) { - } - - function acceptsEventEmitterClass(eventEmitter: events.EventEmitter) { - } - - acceptsEventEmitterInterface(emitter); - acceptsEventEmitterClass(emitter); -} - -{ - class Extended extends events.EventEmitter {} - - class DoubleExtension extends Extended {} - - const extended = new Extended(); - const doubleExtended = new DoubleExtension(); - - events.on(extended, "event1"); // $ExpectType AsyncIterator<[string, number], any, any> - events.once(extended, "event1"); // $ExpectType Promise<[string, number]> - - events.on(extended, "unknown"); // $ExpectType AsyncIterator - events.once(extended, "unknown"); // $ExpectType Promise - - events.on(doubleExtended, "event1"); // $ExpectType AsyncIterator<[string, number], any, any> - events.once(doubleExtended, "event1"); // $ExpectType Promise<[string, number]> - - events.on(doubleExtended, "unknown"); // $ExpectType AsyncIterator - events.once(doubleExtended, "unknown"); // $ExpectType Promise - - extended.addListener(event1, (a: string, b: number | boolean): number => 1); - doubleExtended.addListener(event1, (a: string, b: number | boolean): number => 1); - // @ts-expect-error - extended.addListener(event1, (a: string, b: boolean): number => 1); - // @ts-expect-error - doubleExtended.addListener(event1, (a: string, b: boolean): number => 1); - - extended.emit("event1", "hello", 42); - doubleExtended.emit("event1", "hello", 42); - // @ts-expect-error - extended.emit("event1", 123); - // @ts-expect-error - doubleExtended.emit("event1", 123); + emitter.emit(s2, "hello", false); } diff --git a/types/node/v16/events.d.ts b/types/node/v16/events.d.ts index d0c6d115556ea6..3d5830a2578153 100644 --- a/types/node/v16/events.d.ts +++ b/types/node/v16/events.d.ts @@ -34,7 +34,6 @@ * ``` * @see [source](https://github.com/nodejs/node/blob/v16.9.0/lib/events.js) */ - declare module "events" { import { AsyncResource, AsyncResourceOptions } from "node:async_hooks"; @@ -57,33 +56,25 @@ declare module "events" { ): any; } interface StaticEventEmitterOptions { - /** - * Can be used to cancel awaiting events. - */ signal?: AbortSignal | undefined; } - interface EventEmitter = {}> extends NodeJS.EventEmitter {} - type EventMap = Record; - type Args, EventName> = EventName extends keyof Events ? ( - | Events[EventName] - | (EventName extends keyof EventEmitter.EventEmitterBuiltInEventMap - ? EventEmitter.EventEmitterBuiltInEventMap[EventName] - : never) - ) - : (EventName extends keyof EventEmitter.EventEmitterBuiltInEventMap - ? EventEmitter.EventEmitterBuiltInEventMap[EventName] - : any[]); - type EventNames> = {} extends Events ? (string | symbol) - : (keyof Events | keyof EventEmitter.EventEmitterBuiltInEventMap); - type Listener, EventName> = EventName extends keyof Events ? - | ((...args: Events[EventName]) => void) - | (EventName extends keyof EventEmitter.EventEmitterBuiltInEventMap - ? (...args: EventEmitter.EventEmitterBuiltInEventMap[EventName]) => void - : never) - : (EventName extends keyof EventEmitter.EventEmitterBuiltInEventMap - ? (...args: EventEmitter.EventEmitterBuiltInEventMap[EventName]) => void - : (...args: any[]) => void); - + interface EventEmitter = DefaultEventMap> extends NodeJS.EventEmitter {} + type EventMap = Record | DefaultEventMap; + type DefaultEventMap = [never]; + type AnyRest = [...args: any[]]; + type Args = T extends DefaultEventMap ? AnyRest : ( + K extends keyof T ? T[K] : never + ); + type Key = T extends DefaultEventMap ? string | symbol : K | keyof T; + type Key2 = T extends DefaultEventMap ? string | symbol : K & keyof T; + type Listener = T extends DefaultEventMap ? F : ( + K extends keyof T ? ( + T[K] extends unknown[] ? (...args: T[K]) => void : never + ) + : never + ); + type Listener1 = Listener void>; + type Listener2 = Listener; /** * The `EventEmitter` class is defined and exposed by the `events` module: * @@ -97,20 +88,10 @@ declare module "events" { * It supports the following option: * @since v0.1.26 */ - class EventEmitter = {}> { + class EventEmitter = DefaultEventMap> { constructor(options?: EventEmitterOptions); - // This "property" is used to brand a specific instance of the EventEmitter class with its Event map, which is needed - // in order to infer the map if we have a chain like `class A extends EventEmitter<{}>` (or many levels deep) - // It is also marked as possibly undefined in order to allow something like `const t: NodeJS.EventEmitter<{}> = { };` - readonly #internalTypeOnlyBrand?: Events; - - [EventEmitter.captureRejectionSymbol]?>( - error: Error, - event: EventName, - ...args: Args - ): void; - [EventEmitter.captureRejectionSymbol]?(error: Error, event: string | symbol, ...args: any[]): void; + [EventEmitter.captureRejectionSymbol]?(error: Error, event: Key, ...args: Args): void; /** * Creates a `Promise` that is fulfilled when the `EventEmitter` emits the given @@ -149,7 +130,7 @@ declare module "events" { * run(); * ``` * - * The special handling of the `'error'` event is only used when `events.once()` is used to wait for another event. If `events.once()` is used to wait for the + * The special handling of the `'error'` event is only used when `events.once()`is used to wait for another event. If `events.once()` is used to wait for the * '`error'` event itself, then it is treated as any other kind of event without * special handling: * @@ -160,7 +141,7 @@ declare module "events" { * * once(ee, 'error') * .then(([err]) => console.log('ok', err.message)) - * .catch((err) => console.error('error', err.message)); + * .catch((err) => console.log('error', err.message)); * * ee.emit('error', new Error('boom')); * @@ -194,11 +175,6 @@ declare module "events" { * ``` * @since v11.13.0, v10.16.0 */ - static once, EventName extends EventNames>( - emitter: EventEmitter, - eventName: EventName, - options?: StaticEventEmitterOptions, - ): Promise>; static once( emitter: NodeEventTarget, eventName: string | symbol, @@ -260,20 +236,16 @@ declare module "events" { * process.nextTick(() => ac.abort()); * ``` * @since v13.6.0, v12.16.0 - * @return An `AsyncIterator` that iterates `eventName` events emitted by the `emitter` + * @param eventName The name of the event being listened for + * @return that iterates `eventName` events emitted by the `emitter` */ - static on, EventName extends EventNames>( - emitter: EventEmitter, - eventName: EventName, - options?: StaticEventEmitterOptions, - ): NodeJS.AsyncIterator>; static on( emitter: NodeJS.EventEmitter, - eventName: string | symbol, + eventName: string, options?: StaticEventEmitterOptions, - ): NodeJS.AsyncIterator; + ): NodeJS.AsyncIterator; /** - * A class method that returns the number of listeners for the given `eventName` registered on the given `emitter`. + * A class method that returns the number of listeners for the given `eventName`registered on the given `emitter`. * * ```js * import { EventEmitter, listenerCount } from 'node:events'; @@ -288,27 +260,6 @@ declare module "events" { * @param emitter The emitter to query * @param eventName The event name */ - static listenerCount, EventName extends EventNames>( - emitter: EventEmitter, - eventName: EventName, - ): number; - /** - * A class method that returns the number of listeners for the given `eventName` registered on the given `emitter`. - * - * ```js - * const { EventEmitter, listenerCount } = require('events'); - * - * const myEmitter = new EventEmitter(); - * myEmitter.on('event', () => {}); - * myEmitter.on('event', () => {}); - * console.log(listenerCount(myEmitter, 'event')); - * // Prints: 2 - * ``` - * @since v0.9.12 - * @deprecated Since v3.2.0 - Use `listenerCount` instead. - * @param emitter The emitter to query - * @param eventName The event name - */ static listenerCount(emitter: NodeJS.EventEmitter, eventName: string | symbol): number; /** * Returns a copy of the array of listeners for the event named `eventName`. @@ -326,21 +277,17 @@ declare module "events" { * const ee = new EventEmitter(); * const listener = () => console.log('Events are fun'); * ee.on('foo', listener); - * console.log(getEventListeners(ee, 'foo')); // [ [Function: listener] ] + * getEventListeners(ee, 'foo'); // [listener] * } * { * const et = new EventTarget(); * const listener = () => console.log('Events are fun'); * et.addEventListener('foo', listener); - * console.log(getEventListeners(et, 'foo')); // [ [Function: listener] ] + * getEventListeners(et, 'foo'); // [listener] * } * ``` - * @since v15.2.0, v14.17.0 + * @since v15.2.0 */ - static getEventListeners, EventName extends EventNames>( - emitter: EventEmitter, - name: EventName, - ): Array>; static getEventListeners(emitter: DOMEventTarget | NodeJS.EventEmitter, name: string | symbol): Function[]; /** * ```js @@ -361,65 +308,21 @@ declare module "events" { */ static setMaxListeners(n?: number, ...eventTargets: Array): void; /** - * This symbol shall be used to install a listener for only monitoring `'error'` events. Listeners installed using this symbol are called before the regular `'error'` listeners are called. + * This symbol shall be used to install a listener for only monitoring `'error'` + * events. Listeners installed using this symbol are called before the regular + * `'error'` listeners are called. * - * Installing a listener using this symbol does not change the behavior once an `'error'` event is emitted. Therefore, the process will still crash if no + * Installing a listener using this symbol does not change the behavior once an + * `'error'` event is emitted, therefore the process will still crash if no * regular `'error'` listener is installed. - * @since v13.6.0, v12.17.0 */ static readonly errorMonitor: unique symbol; - /** - * Value: `Symbol.for('nodejs.rejection')` - * - * See how to write a custom `rejection handler`. - * @since v13.4.0, v12.16.0 - */ static readonly captureRejectionSymbol: unique symbol; /** - * Value: [boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type) - * - * Change the default `captureRejections` option on all new `EventEmitter` objects. - * @since v13.4.0, v12.16.0 + * Sets or gets the default captureRejection value for all emitters. */ + // TODO: These should be described using static getter/setter pairs: static captureRejections: boolean; - /** - * By default, a maximum of `10` listeners can be registered for any single - * event. This limit can be changed for individual `EventEmitter` instances - * using the `emitter.setMaxListeners(n)` method. To change the default - * for _all_`EventEmitter` instances, the `events.defaultMaxListeners` property - * can be used. If this value is not a positive number, a `RangeError` is thrown. - * - * Take caution when setting the `events.defaultMaxListeners` because the - * change affects _all_ `EventEmitter` instances, including those created before - * the change is made. However, calling `emitter.setMaxListeners(n)` still has - * precedence over `events.defaultMaxListeners`. - * - * This is not a hard limit. The `EventEmitter` instance will allow - * more listeners to be added but will output a trace warning to stderr indicating - * that a "possible EventEmitter memory leak" has been detected. For any single - * `EventEmitter`, the `emitter.getMaxListeners()` and `emitter.setMaxListeners()` methods can be used to - * temporarily avoid this warning: - * - * ```js - * const EventEmitter = require('events'); - * const emitter = new EventEmitter(); - * emitter.setMaxListeners(emitter.getMaxListeners() + 1); - * emitter.once('event', () => { - * // do stuff - * emitter.setMaxListeners(Math.max(emitter.getMaxListeners() - 1, 0)); - * }); - * ``` - * - * The `--trace-warnings` command-line flag can be used to display the - * stack trace for such warnings. - * - * The emitted warning can be inspected with `process.on('warning')` and will - * have the additional `emitter`, `type`, and `count` properties, referring to - * the event emitter instance, the event's name and the number of attached - * listeners, respectively. - * Its `name` property is set to `'MaxListenersExceededWarning'`. - * @since v0.11.2 - */ static defaultMaxListeners: number; } import internal = require("node:events"); @@ -447,41 +350,13 @@ declare module "events" { } /** - * Integrates `EventEmitter` with `AsyncResource` for `EventEmitter`s that - * require manual async tracking. Specifically, all events emitted by instances - * of `events.EventEmitterAsyncResource` will run within its `async context`. + * Integrates `EventEmitter` with `AsyncResource` for `EventEmitter`s that require + * manual async tracking. Specifically, all events emitted by instances of + * `EventEmitterAsyncResource` will run within its async context. * - * ```js - * const { EventEmitterAsyncResource, EventEmitter } = require('events'); - * const { notStrictEqual, strictEqual } = require('assert'); - * const { executionAsyncId, triggerAsyncId } = require('async_hooks'); - * - * // Async tracking tooling will identify this as 'Q'. - * const ee1 = new EventEmitterAsyncResource({ name: 'Q' }); - * - * // 'foo' listeners will run in the EventEmitters async context. - * ee1.on('foo', () => { - * strictEqual(executionAsyncId(), ee1.asyncId); - * strictEqual(triggerAsyncId(), ee1.triggerAsyncId); - * }); - * - * const ee2 = new EventEmitter(); - * - * // 'foo' listeners on ordinary EventEmitters that do not track async - * // context, however, run in the same async context as the emit(). - * ee2.on('foo', () => { - * notStrictEqual(executionAsyncId(), ee2.asyncId); - * notStrictEqual(triggerAsyncId(), ee2.triggerAsyncId); - * }); - * - * Promise.resolve().then(() => { - * ee1.emit('foo'); - * ee2.emit('foo'); - * }); - * ``` - * - * The `EventEmitterAsyncResource` class has the same methods and takes the - * same options as `EventEmitter` and `AsyncResource` themselves. + * The EventEmitterAsyncResource class has the same methods and takes the + * same options as EventEmitter and AsyncResource themselves. + * @throws if `options.name` is not provided when instantiated directly. * @since v17.4.0, v16.14.0 */ export class EventEmitterAsyncResource extends EventEmitter { @@ -490,62 +365,34 @@ declare module "events" { */ constructor(options?: EventEmitterAsyncResourceOptions); /** - * Call all `destroy` hooks. This should only ever be called once. An error will - * be thrown if it is called more than once. This **must** be manually called. If - * the resource is left to be collected by the GC then the `destroy` hooks will - * never be called. + * Call all destroy hooks. This should only ever be called once. An + * error will be thrown if it is called more than once. This must be + * manually called. If the resource is left to be collected by the GC then + * the destroy hooks will never be called. */ emitDestroy(): void; - /** - * The unique `asyncId` assigned to the resource. - */ + /** The unique asyncId assigned to the resource. */ readonly asyncId: number; - /** - * The same triggerAsyncId that is passed to the AsyncResource constructor. - */ + /** The same triggerAsyncId that is passed to the AsyncResource constructor. */ readonly triggerAsyncId: number; - /** - * The returned `AsyncResource` object has an additional `eventEmitter` property - * that provides a reference to this `EventEmitterAsyncResource`. - */ + /** The underlying AsyncResource */ readonly asyncResource: EventEmitterReferencingAsyncResource; } - - export interface EventEmitterBuiltInEventMap { - newListener: [eventName: string | symbol, listener: Function]; - removeListener: [eventName: string | symbol, listener: Function]; - } } global { namespace NodeJS { - interface EventEmitter = {}> { - [EventEmitter.captureRejectionSymbol]?>( - error: Error, - event: EventName, - ...args: Args - ): void; - [EventEmitter.captureRejectionSymbol]?( - error: Error, - event: EventName, - ...args: Args - ): void; + interface EventEmitter = DefaultEventMap> { + [EventEmitter.captureRejectionSymbol]?(error: Error, event: Key, ...args: Args): void; /** * Alias for `emitter.on(eventName, listener)`. * @since v0.1.26 */ - addListener>( - eventName: EventName, - listener: Listener, - ): this; - addListener( - eventName: EventName, - listener: Listener, - ): this; + addListener(eventName: Key, listener: Listener1): this; /** - * Adds the `listener` function to the end of the listeners array for the event - * named `eventName`. No checks are made to see if the `listener` has already - * been added. Multiple calls passing the same combination of `eventName` and - * `listener` will result in the `listener` being added, and called, multiple times. + * Adds the `listener` function to the end of the listeners array for the + * event named `eventName`. No checks are made to see if the `listener` has + * already been added. Multiple calls passing the same combination of `eventName` and `listener` will result in the `listener` being added, and called, multiple + * times. * * ```js * server.on('connection', (stream) => { @@ -555,11 +402,10 @@ declare module "events" { * * Returns a reference to the `EventEmitter`, so that calls can be chained. * - * By default, event listeners are invoked in the order they are added. The `emitter.prependListener()` method can be used as an alternative to add the + * By default, event listeners are invoked in the order they are added. The`emitter.prependListener()` method can be used as an alternative to add the * event listener to the beginning of the listeners array. * * ```js - * const EventEmitter = require('events'); * const myEE = new EventEmitter(); * myEE.on('foo', () => console.log('a')); * myEE.prependListener('foo', () => console.log('b')); @@ -572,16 +418,9 @@ declare module "events" { * @param eventName The name of the event. * @param listener The callback function */ - on>( - eventName: EventName, - listener: Listener, - ): this; - on( - eventName: EventName, - listener: Listener, - ): this; + on(eventName: Key, listener: Listener1): this; /** - * Adds a **one-time** `listener` function for the event named `eventName`. The + * Adds a **one-time**`listener` function for the event named `eventName`. The * next time `eventName` is triggered, this listener is removed and then invoked. * * ```js @@ -592,11 +431,10 @@ declare module "events" { * * Returns a reference to the `EventEmitter`, so that calls can be chained. * - * By default, event listeners are invoked in the order they are added. The `emitter.prependOnceListener()` method can be used as an alternative to add the + * By default, event listeners are invoked in the order they are added. The`emitter.prependOnceListener()` method can be used as an alternative to add the * event listener to the beginning of the listeners array. * * ```js - * const EventEmitter = require('events'); * const myEE = new EventEmitter(); * myEE.once('foo', () => console.log('a')); * myEE.prependOnceListener('foo', () => console.log('b')); @@ -609,16 +447,9 @@ declare module "events" { * @param eventName The name of the event. * @param listener The callback function */ - once>( - eventName: EventName, - listener: Listener, - ): this; - once( - eventName: EventName, - listener: Listener, - ): this; + once(eventName: Key, listener: Listener1): this; /** - * Removes the specified `listener` from the listener array for the event named `eventName`. + * Removes the specified `listener` from the listener array for the event named`eventName`. * * ```js * const callback = (stream) => { @@ -635,12 +466,10 @@ declare module "events" { * called multiple times to remove each instance. * * Once an event is emitted, all listeners attached to it at the - * time of emitting are called in order. This implies that any `removeListener()` or `removeAllListeners()` calls _after_ emitting and _before_ the last listener finishes execution - * will not remove them from`emit()` in progress. Subsequent events behave as expected. + * time of emitting are called in order. This implies that any`removeListener()` or `removeAllListeners()` calls _after_ emitting and_before_ the last listener finishes execution will + * not remove them from`emit()` in progress. Subsequent events behave as expected. * * ```js - * const EventEmitter = require('events'); - * class MyEmitter extends EventEmitter {} * const myEmitter = new MyEmitter(); * * const callbackA = () => { @@ -678,10 +507,9 @@ declare module "events" { * * When a single function has been added as a handler multiple times for a single * event (as in the example below), `removeListener()` will remove the most - * recently added instance. In the example the `once('ping')` listener is removed: + * recently added instance. In the example the `once('ping')`listener is removed: * * ```js - * const EventEmitter = require('events'); * const ee = new EventEmitter(); * * function pong() { @@ -699,26 +527,12 @@ declare module "events" { * Returns a reference to the `EventEmitter`, so that calls can be chained. * @since v0.1.26 */ - removeListener>( - eventName: EventName, - listener: Listener, - ): this; - removeListener( - eventName: EventName, - listener: Listener, - ): this; + removeListener(eventName: Key, listener: Listener1): this; /** * Alias for `emitter.removeListener()`. * @since v10.0.0 */ - off>( - eventName: EventName, - listener: Listener, - ): this; - off( - eventName: EventName, - listener: Listener, - ): this; + off(eventName: Key, listener: Listener1): this; /** * Removes all listeners, or those of the specified `eventName`. * @@ -729,15 +543,12 @@ declare module "events" { * Returns a reference to the `EventEmitter`, so that calls can be chained. * @since v0.1.26 */ - /* eslint-disable @definitelytyped/no-unnecessary-generics */ - removeAllListeners>(eventName: EventName): this; - removeAllListeners(eventName?: EventName): this; - /* eslint-enable @definitelytyped/no-unnecessary-generics */ + removeAllListeners(event?: Key): this; /** * By default `EventEmitter`s will print a warning if more than `10` listeners are * added for a particular event. This is a useful default that helps finding * memory leaks. The `emitter.setMaxListeners()` method allows the limit to be - * modified for this specific `EventEmitter` instance. The value can be set to `Infinity` (or `0`) to indicate an unlimited number of listeners. + * modified for this specific `EventEmitter` instance. The value can be set to`Infinity` (or `0`) to indicate an unlimited number of listeners. * * Returns a reference to the `EventEmitter`, so that calls can be chained. * @since v0.3.5 @@ -761,18 +572,12 @@ declare module "events" { * ``` * @since v0.1.26 */ - listeners>( - eventName: EventName, - ): Array>; - listeners( - eventName: EventName, - ): Array>; + listeners(eventName: Key): Array>; /** * Returns a copy of the array of listeners for the event named `eventName`, * including any wrappers (such as those created by `.once()`). * * ```js - * const EventEmitter = require('events'); * const emitter = new EventEmitter(); * emitter.once('log', () => console.log('log once')); * @@ -797,14 +602,9 @@ declare module "events" { * ``` * @since v9.4.0 */ - rawListeners>( - eventName: EventName, - ): Array>; - rawListeners( - eventName: EventName, - ): Array>; + rawListeners(eventName: Key): Array>; /** - * Synchronously calls each of the listeners registered for the event named `eventName`, in the order they were registered, passing the supplied arguments + * Synchronously calls each of the listeners registered for the event named`eventName`, in the order they were registered, passing the supplied arguments * to each. * * Returns `true` if the event had listeners, `false` otherwise. @@ -843,35 +643,18 @@ declare module "events" { * ``` * @since v0.1.26 */ - emit>( - eventName: EventName, - ...args: Args - ): boolean; - emit( - eventName: EventName, - ...args: Args - ): boolean; + emit(eventName: Key, ...args: Args): boolean; /** - * Returns the number of listeners listening for the event named `eventName`. - * If `listener` is provided, it will return how many times the listener is found - * in the list of the listeners of the event. + * Returns the number of listeners listening to the event named `eventName`. * @since v3.2.0 * @param eventName The name of the event being listened for - * @param listener The event handler function */ - listenerCount>( - eventName: EventName, - listener?: Listener, - ): number; - listenerCount( - eventName: EventName, - listener?: Listener, - ): number; + listenerCount(eventName: Key, listener?: Listener2): number; /** * Adds the `listener` function to the _beginning_ of the listeners array for the * event named `eventName`. No checks are made to see if the `listener` has - * already been added. Multiple calls passing the same combination of `eventName` - * and `listener` will result in the `listener` being added, and called, multiple times. + * already been added. Multiple calls passing the same combination of `eventName` and `listener` will result in the `listener` being added, and called, multiple + * times. * * ```js * server.prependListener('connection', (stream) => { @@ -884,16 +667,9 @@ declare module "events" { * @param eventName The name of the event. * @param listener The callback function */ - prependListener>( - eventName: EventName, - listener: Listener, - ): this; - prependListener( - eventName: EventName, - listener: Listener, - ): this; + prependListener(eventName: Key, listener: Listener1): this; /** - * Adds a **one-time**`listener` function for the event named `eventName` to the _beginning_ of the listeners array. The next time `eventName` is triggered, this + * Adds a **one-time**`listener` function for the event named `eventName` to the_beginning_ of the listeners array. The next time `eventName` is triggered, this * listener is removed, and then invoked. * * ```js @@ -907,14 +683,7 @@ declare module "events" { * @param eventName The name of the event. * @param listener The callback function */ - prependOnceListener>( - eventName: EventName, - listener: Listener, - ): this; - prependOnceListener( - eventName: EventName, - listener: Listener, - ): this; + prependOnceListener(eventName: Key, listener: Listener1): this; /** * Returns an array listing the events for which the emitter has registered * listeners. The values in the array are strings or `Symbol`s. @@ -933,7 +702,7 @@ declare module "events" { * ``` * @since v6.0.0 */ - eventNames(): Array<(string | symbol)> & Array>; + eventNames(): Array<(string | symbol) & Key2>; } } } diff --git a/types/node/v16/test/events_generic.ts b/types/node/v16/test/events_generic.ts index 35a088ec8d2ef0..a40882f0bea35a 100644 --- a/types/node/v16/test/events_generic.ts +++ b/types/node/v16/test/events_generic.ts @@ -110,17 +110,13 @@ declare const event5: "event5"; } { - let result1: Promise; - let result2: Promise; - let result3: Promise; - let result4: Promise; - let result5: Promise; - - result1 = events.once(emitter, event1); - result2 = events.once(emitter, event2); - result3 = events.once(emitter, event3); - result4 = events.once(emitter, event4); - result5 = events.once(emitter, event5); + let result: Promise; + + result = events.once(emitter, event1); + result = events.once(emitter, event2); + result = events.once(emitter, event3); + result = events.once(emitter, event4); + result = events.once(emitter, event5); emitter.emit("event1", "hello", 42); emitter.emit("event2", true); @@ -150,7 +146,7 @@ declare const event5: "event5"; } { - let result: Array; + let result: Array; result = emitter.eventNames(); } @@ -161,12 +157,12 @@ declare const event5: "event5"; ) : never; - function on1(event: K, listener: Listener): void { + function on1(event: K, listener: Listener): void { emitter.on(event, listener); } // eslint-disable-next-line @definitelytyped/no-unnecessary-generics - function on2(...args: Parameters>): void { + function on2(...args: Parameters>): void { emitter.on(...args); } @@ -208,6 +204,7 @@ declare const event5: "event5"; emitter.emit("abc", "hello", 123); // @ts-expect-error emitter.emit("abc", 123, false); + // @ts-expect-error emitter.emit("def", "hello", 123); } @@ -229,6 +226,7 @@ declare const event5: "event5"; emitter.emit(s1, "hello", 123); // @ts-expect-error emitter.emit(s1, 123, false); + // @ts-expect-error emitter.emit(s2, "hello", 123); } @@ -246,71 +244,6 @@ declare const event5: "event5"; emitter.emit(789, 123, false); // @ts-expect-error emitter.emit(s1, "hello", false); - emitter.emit(s2, "hello", false); -} - -{ - const promise1: Promise<[string, number]> = events.once(new events.EventEmitter(), "event1"); - const promise2: Promise<[boolean]> = events.once(new events.EventEmitter(), "event2"); - const promise3: Promise<[]> = events.once(new events.EventEmitter(), "event3"); - const promise4: Promise = events.once(new events.EventEmitter(), "event4"); - const promise5: Promise = events.once(new events.EventEmitter(), "event5"); - // @ts-expect-error - const promise6: Promise<[string, string]> = events.once(new events.EventEmitter(), "event1"); - const promise7: Promise = events.once(new events.EventEmitter(), "event"); - - const iterable1: NodeJS.AsyncIterator<[string, number]> = events.on(new events.EventEmitter(), "event1"); - const iterable2: NodeJS.AsyncIterator<[boolean]> = events.on(new events.EventEmitter(), "event2"); - const iterable3: NodeJS.AsyncIterator<[]> = events.on(new events.EventEmitter(), "event3"); - const iterable4: NodeJS.AsyncIterator = events.on(new events.EventEmitter(), "event4"); - const iterable5: NodeJS.AsyncIterator = events.on(new events.EventEmitter(), "event5"); // @ts-expect-error - const iterable6: NodeJS.AsyncIterator<[string, string]> = events.on(new events.EventEmitter(), "event1"); - const iterable7: NodeJS.AsyncIterator = events.on(new events.EventEmitter(), "event"); -} - -{ - function acceptsEventEmitterInterface(eventEmitter: NodeJS.EventEmitter) { - } - - function acceptsEventEmitterClass(eventEmitter: events.EventEmitter) { - } - - acceptsEventEmitterInterface(emitter); - acceptsEventEmitterClass(emitter); -} - -{ - class Extended extends events.EventEmitter {} - - class DoubleExtension extends Extended {} - - const extended = new Extended(); - const doubleExtended = new DoubleExtension(); - - events.on(extended, "event1"); // $ExpectType AsyncIterator<[string, number], any, any> - events.once(extended, "event1"); // $ExpectType Promise<[string, number]> - - events.on(extended, "unknown"); // $ExpectType AsyncIterator - events.once(extended, "unknown"); // $ExpectType Promise - - events.on(doubleExtended, "event1"); // $ExpectType AsyncIterator<[string, number], any, any> - events.once(doubleExtended, "event1"); // $ExpectType Promise<[string, number]> - - events.on(doubleExtended, "unknown"); // $ExpectType AsyncIterator - events.once(doubleExtended, "unknown"); // $ExpectType Promise - - extended.addListener(event1, (a: string, b: number | boolean): number => 1); - doubleExtended.addListener(event1, (a: string, b: number | boolean): number => 1); - // @ts-expect-error - extended.addListener(event1, (a: string, b: boolean): number => 1); - // @ts-expect-error - doubleExtended.addListener(event1, (a: string, b: boolean): number => 1); - - extended.emit("event1", "hello", 42); - doubleExtended.emit("event1", "hello", 42); - // @ts-expect-error - extended.emit("event1", 123); - // @ts-expect-error - doubleExtended.emit("event1", 123); + emitter.emit(s2, "hello", false); } diff --git a/types/node/v18/events.d.ts b/types/node/v18/events.d.ts index 8bf77e2952fbf3..e92a74945471f9 100644 --- a/types/node/v18/events.d.ts +++ b/types/node/v18/events.d.ts @@ -34,12 +34,13 @@ * ``` * @see [source](https://github.com/nodejs/node/blob/v18.0.0/lib/events.js) */ - declare module "events" { import { AsyncResource, AsyncResourceOptions } from "node:async_hooks"; + // NOTE: This class is in the docs but is **not actually exported** by Node. // If https://github.com/nodejs/node/issues/39903 gets resolved and Node // actually starts exporting the class, uncomment below. + // import { EventListener, EventListenerObject } from '__dom-events'; // /** The NodeEventTarget is a Node.js-specific extension to EventTarget that emulates a subset of the EventEmitter API. */ // interface NodeEventTarget extends EventTarget { @@ -70,6 +71,7 @@ declare module "events" { // */ // removeListener(type: string, listener: EventListener | EventListenerObject): this; // } + interface EventEmitterOptions { /** * Enables automatic capturing of promise rejection. @@ -91,33 +93,25 @@ declare module "events" { ): any; } interface StaticEventEmitterOptions { - /** - * Can be used to cancel awaiting events. - */ signal?: AbortSignal | undefined; } - interface EventEmitter = {}> extends NodeJS.EventEmitter {} - type EventMap = Record; - type Args, EventName> = EventName extends keyof Events ? ( - | Events[EventName] - | (EventName extends keyof EventEmitter.EventEmitterBuiltInEventMap - ? EventEmitter.EventEmitterBuiltInEventMap[EventName] - : never) - ) - : (EventName extends keyof EventEmitter.EventEmitterBuiltInEventMap - ? EventEmitter.EventEmitterBuiltInEventMap[EventName] - : any[]); - type EventNames> = {} extends Events ? (string | symbol) - : (keyof Events | keyof EventEmitter.EventEmitterBuiltInEventMap); - type Listener, EventName> = EventName extends keyof Events ? - | ((...args: Events[EventName]) => void) - | (EventName extends keyof EventEmitter.EventEmitterBuiltInEventMap - ? (...args: EventEmitter.EventEmitterBuiltInEventMap[EventName]) => void - : never) - : (EventName extends keyof EventEmitter.EventEmitterBuiltInEventMap - ? (...args: EventEmitter.EventEmitterBuiltInEventMap[EventName]) => void - : (...args: any[]) => void); - + interface EventEmitter = DefaultEventMap> extends NodeJS.EventEmitter {} + type EventMap = Record | DefaultEventMap; + type DefaultEventMap = [never]; + type AnyRest = [...args: any[]]; + type Args = T extends DefaultEventMap ? AnyRest : ( + K extends keyof T ? T[K] : never + ); + type Key = T extends DefaultEventMap ? string | symbol : K | keyof T; + type Key2 = T extends DefaultEventMap ? string | symbol : K & keyof T; + type Listener = T extends DefaultEventMap ? F : ( + K extends keyof T ? ( + T[K] extends unknown[] ? (...args: T[K]) => void : never + ) + : never + ); + type Listener1 = Listener void>; + type Listener2 = Listener; /** * The `EventEmitter` class is defined and exposed by the `events` module: * @@ -131,20 +125,10 @@ declare module "events" { * It supports the following option: * @since v0.1.26 */ - class EventEmitter = {}> { + class EventEmitter = DefaultEventMap> { constructor(options?: EventEmitterOptions); - // This "property" is used to brand a specific instance of the EventEmitter class with its Event map, which is needed - // in order to infer the map if we have a chain like `class A extends EventEmitter<{}>` (or many levels deep) - // It is also marked as possibly undefined in order to allow something like `const t: NodeJS.EventEmitter<{}> = { };` - readonly #internalTypeOnlyBrand?: Events; - - [EventEmitter.captureRejectionSymbol]?>( - error: Error, - event: EventName, - ...args: Args - ): void; - [EventEmitter.captureRejectionSymbol]?(error: Error, event: string | symbol, ...args: any[]): void; + [EventEmitter.captureRejectionSymbol]?(error: Error, event: Key, ...args: Args): void; /** * Creates a `Promise` that is fulfilled when the `EventEmitter` emits the given @@ -228,11 +212,6 @@ declare module "events" { * ``` * @since v11.13.0, v10.16.0 */ - static once, EventName extends EventNames>( - emitter: EventEmitter, - eventName: EventName, - options?: StaticEventEmitterOptions, - ): Promise>; static once( emitter: _NodeEventTarget, eventName: string | symbol, @@ -294,20 +273,16 @@ declare module "events" { * process.nextTick(() => ac.abort()); * ``` * @since v13.6.0, v12.16.0 - * @return An `AsyncIterator` that iterates `eventName` events emitted by the `emitter` + * @param eventName The name of the event being listened for + * @return that iterates `eventName` events emitted by the `emitter` */ - static on, EventName extends EventNames>( - emitter: EventEmitter, - eventName: EventName, - options?: StaticEventEmitterOptions, - ): NodeJS.AsyncIterator>; static on( emitter: NodeJS.EventEmitter, - eventName: string | symbol, + eventName: string, options?: StaticEventEmitterOptions, - ): NodeJS.AsyncIterator; + ): NodeJS.AsyncIterator; /** - * A class method that returns the number of listeners for the given `eventName` registered on the given `emitter`. + * A class method that returns the number of listeners for the given `eventName`registered on the given `emitter`. * * ```js * import { EventEmitter, listenerCount } from 'node:events'; @@ -322,27 +297,6 @@ declare module "events" { * @param emitter The emitter to query * @param eventName The event name */ - static listenerCount, EventName extends EventNames>( - emitter: EventEmitter, - eventName: EventName, - ): number; - /** - * A class method that returns the number of listeners for the given `eventName` registered on the given `emitter`. - * - * ```js - * const { EventEmitter, listenerCount } = require('events'); - * - * const myEmitter = new EventEmitter(); - * myEmitter.on('event', () => {}); - * myEmitter.on('event', () => {}); - * console.log(listenerCount(myEmitter, 'event')); - * // Prints: 2 - * ``` - * @since v0.9.12 - * @deprecated Since v3.2.0 - Use `listenerCount` instead. - * @param emitter The emitter to query - * @param eventName The event name - */ static listenerCount(emitter: NodeJS.EventEmitter, eventName: string | symbol): number; /** * Returns a copy of the array of listeners for the event named `eventName`. @@ -360,21 +314,17 @@ declare module "events" { * const ee = new EventEmitter(); * const listener = () => console.log('Events are fun'); * ee.on('foo', listener); - * console.log(getEventListeners(ee, 'foo')); // [ [Function: listener] ] + * getEventListeners(ee, 'foo'); // [listener] * } * { * const et = new EventTarget(); * const listener = () => console.log('Events are fun'); * et.addEventListener('foo', listener); - * console.log(getEventListeners(et, 'foo')); // [ [Function: listener] ] + * getEventListeners(et, 'foo'); // [listener] * } * ``` * @since v15.2.0, v14.17.0 */ - static getEventListeners, EventName extends EventNames>( - emitter: EventEmitter, - name: EventName, - ): Array>; static getEventListeners(emitter: _DOMEventTarget | NodeJS.EventEmitter, name: string | symbol): Function[]; /** * Returns the currently set max amount of listeners. @@ -387,7 +337,7 @@ declare module "events" { * the max set, the EventTarget will print a warning. * * ```js - * const { getMaxListeners, setMaxListeners, EventEmitter } = require('events'); + * import { getMaxListeners, setMaxListeners, EventEmitter } from 'node:events'; * * { * const ee = new EventEmitter(); @@ -439,7 +389,7 @@ declare module "events" { * Returns a disposable so that it may be unsubscribed from more easily. * * ```js - * const { addAbortListener } = require('events'); + * import { addAbortListener } from 'node:events'; * * function example(signal) { * let disposable; @@ -468,58 +418,12 @@ declare module "events" { * regular `'error'` listener is installed. */ static readonly errorMonitor: unique symbol; - /** - * Value: `Symbol.for('nodejs.rejection')` - * - * See how to write a custom `rejection handler`. - * @since v13.4.0, v12.16.0 - */ static readonly captureRejectionSymbol: unique symbol; /** - * Value: [boolean](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type) - * - * Change the default `captureRejections` option on all new `EventEmitter` objects. - * @since v13.4.0, v12.16.0 + * Sets or gets the default captureRejection value for all emitters. */ + // TODO: These should be described using static getter/setter pairs: static captureRejections: boolean; - /** - * By default, a maximum of `10` listeners can be registered for any single - * event. This limit can be changed for individual `EventEmitter` instances - * using the `emitter.setMaxListeners(n)` method. To change the default - * for _all_`EventEmitter` instances, the `events.defaultMaxListeners` property - * can be used. If this value is not a positive number, a `RangeError` is thrown. - * - * Take caution when setting the `events.defaultMaxListeners` because the - * change affects _all_ `EventEmitter` instances, including those created before - * the change is made. However, calling `emitter.setMaxListeners(n)` still has - * precedence over `events.defaultMaxListeners`. - * - * This is not a hard limit. The `EventEmitter` instance will allow - * more listeners to be added but will output a trace warning to stderr indicating - * that a "possible EventEmitter memory leak" has been detected. For any single - * `EventEmitter`, the `emitter.getMaxListeners()` and `emitter.setMaxListeners()` methods can be used to - * temporarily avoid this warning: - * - * ```js - * const EventEmitter = require('events'); - * const emitter = new EventEmitter(); - * emitter.setMaxListeners(emitter.getMaxListeners() + 1); - * emitter.once('event', () => { - * // do stuff - * emitter.setMaxListeners(Math.max(emitter.getMaxListeners() - 1, 0)); - * }); - * ``` - * - * The `--trace-warnings` command-line flag can be used to display the - * stack trace for such warnings. - * - * The emitted warning can be inspected with `process.on('warning')` and will - * have the additional `emitter`, `type`, and `count` properties, referring to - * the event emitter instance, the event's name and the number of attached - * listeners, respectively. - * Its `name` property is set to `'MaxListenersExceededWarning'`. - * @since v0.11.2 - */ static defaultMaxListeners: number; } import internal = require("node:events"); @@ -547,41 +451,13 @@ declare module "events" { } /** - * Integrates `EventEmitter` with `AsyncResource` for `EventEmitter`s that - * require manual async tracking. Specifically, all events emitted by instances - * of `events.EventEmitterAsyncResource` will run within its `async context`. - * - * ```js - * const { EventEmitterAsyncResource, EventEmitter } = require('events'); - * const { notStrictEqual, strictEqual } = require('assert'); - * const { executionAsyncId, triggerAsyncId } = require('async_hooks'); - * - * // Async tracking tooling will identify this as 'Q'. - * const ee1 = new EventEmitterAsyncResource({ name: 'Q' }); - * - * // 'foo' listeners will run in the EventEmitters async context. - * ee1.on('foo', () => { - * strictEqual(executionAsyncId(), ee1.asyncId); - * strictEqual(triggerAsyncId(), ee1.triggerAsyncId); - * }); + * Integrates `EventEmitter` with `AsyncResource` for `EventEmitter`s that require + * manual async tracking. Specifically, all events emitted by instances of + * `EventEmitterAsyncResource` will run within its async context. * - * const ee2 = new EventEmitter(); - * - * // 'foo' listeners on ordinary EventEmitters that do not track async - * // context, however, run in the same async context as the emit(). - * ee2.on('foo', () => { - * notStrictEqual(executionAsyncId(), ee2.asyncId); - * notStrictEqual(triggerAsyncId(), ee2.triggerAsyncId); - * }); - * - * Promise.resolve().then(() => { - * ee1.emit('foo'); - * ee2.emit('foo'); - * }); - * ``` - * - * The `EventEmitterAsyncResource` class has the same methods and takes the - * same options as `EventEmitter` and `AsyncResource` themselves. + * The EventEmitterAsyncResource class has the same methods and takes the + * same options as EventEmitter and AsyncResource themselves. + * @throws if `options.name` is not provided when instantiated directly. * @since v17.4.0, v16.14.0 */ export class EventEmitterAsyncResource extends EventEmitter { @@ -590,62 +466,34 @@ declare module "events" { */ constructor(options?: EventEmitterAsyncResourceOptions); /** - * Call all `destroy` hooks. This should only ever be called once. An error will - * be thrown if it is called more than once. This **must** be manually called. If - * the resource is left to be collected by the GC then the `destroy` hooks will - * never be called. + * Call all destroy hooks. This should only ever be called once. An + * error will be thrown if it is called more than once. This must be + * manually called. If the resource is left to be collected by the GC then + * the destroy hooks will never be called. */ emitDestroy(): void; - /** - * The unique `asyncId` assigned to the resource. - */ + /** The unique asyncId assigned to the resource. */ readonly asyncId: number; - /** - * The same triggerAsyncId that is passed to the AsyncResource constructor. - */ + /** The same triggerAsyncId that is passed to the AsyncResource constructor. */ readonly triggerAsyncId: number; - /** - * The returned `AsyncResource` object has an additional `eventEmitter` property - * that provides a reference to this `EventEmitterAsyncResource`. - */ + /** The underlying AsyncResource */ readonly asyncResource: EventEmitterReferencingAsyncResource; } - - export interface EventEmitterBuiltInEventMap { - newListener: [eventName: string | symbol, listener: Function]; - removeListener: [eventName: string | symbol, listener: Function]; - } } global { namespace NodeJS { - interface EventEmitter = {}> { - [EventEmitter.captureRejectionSymbol]?>( - error: Error, - event: EventName, - ...args: Args - ): void; - [EventEmitter.captureRejectionSymbol]?( - error: Error, - event: EventName, - ...args: Args - ): void; + interface EventEmitter = DefaultEventMap> { + [EventEmitter.captureRejectionSymbol]?(error: Error, event: Key, ...args: Args): void; /** * Alias for `emitter.on(eventName, listener)`. * @since v0.1.26 */ - addListener>( - eventName: EventName, - listener: Listener, - ): this; - addListener( - eventName: EventName, - listener: Listener, - ): this; + addListener(eventName: Key, listener: Listener1): this; /** - * Adds the `listener` function to the end of the listeners array for the event - * named `eventName`. No checks are made to see if the `listener` has already - * been added. Multiple calls passing the same combination of `eventName` and - * `listener` will result in the `listener` being added, and called, multiple times. + * Adds the `listener` function to the end of the listeners array for the + * event named `eventName`. No checks are made to see if the `listener` has + * already been added. Multiple calls passing the same combination of `eventName` and `listener` will result in the `listener` being added, and called, multiple + * times. * * ```js * server.on('connection', (stream) => { @@ -655,11 +503,10 @@ declare module "events" { * * Returns a reference to the `EventEmitter`, so that calls can be chained. * - * By default, event listeners are invoked in the order they are added. The `emitter.prependListener()` method can be used as an alternative to add the + * By default, event listeners are invoked in the order they are added. The`emitter.prependListener()` method can be used as an alternative to add the * event listener to the beginning of the listeners array. * * ```js - * const EventEmitter = require('events'); * const myEE = new EventEmitter(); * myEE.on('foo', () => console.log('a')); * myEE.prependListener('foo', () => console.log('b')); @@ -672,16 +519,9 @@ declare module "events" { * @param eventName The name of the event. * @param listener The callback function */ - on>( - eventName: EventName, - listener: Listener, - ): this; - on( - eventName: EventName, - listener: Listener, - ): this; + on(eventName: Key, listener: Listener1): this; /** - * Adds a **one-time** `listener` function for the event named `eventName`. The + * Adds a **one-time**`listener` function for the event named `eventName`. The * next time `eventName` is triggered, this listener is removed and then invoked. * * ```js @@ -692,11 +532,10 @@ declare module "events" { * * Returns a reference to the `EventEmitter`, so that calls can be chained. * - * By default, event listeners are invoked in the order they are added. The `emitter.prependOnceListener()` method can be used as an alternative to add the + * By default, event listeners are invoked in the order they are added. The`emitter.prependOnceListener()` method can be used as an alternative to add the * event listener to the beginning of the listeners array. * * ```js - * const EventEmitter = require('events'); * const myEE = new EventEmitter(); * myEE.once('foo', () => console.log('a')); * myEE.prependOnceListener('foo', () => console.log('b')); @@ -709,16 +548,9 @@ declare module "events" { * @param eventName The name of the event. * @param listener The callback function */ - once>( - eventName: EventName, - listener: Listener, - ): this; - once( - eventName: EventName, - listener: Listener, - ): this; + once(eventName: Key, listener: Listener1): this; /** - * Removes the specified `listener` from the listener array for the event named `eventName`. + * Removes the specified `listener` from the listener array for the event named`eventName`. * * ```js * const callback = (stream) => { @@ -735,12 +567,10 @@ declare module "events" { * called multiple times to remove each instance. * * Once an event is emitted, all listeners attached to it at the - * time of emitting are called in order. This implies that any `removeListener()` or `removeAllListeners()` calls _after_ emitting and _before_ the last listener finishes execution + * time of emitting are called in order. This implies that any`removeListener()` or `removeAllListeners()` calls _after_ emitting and _before_ the last listener finishes execution * will not remove them from`emit()` in progress. Subsequent events behave as expected. * * ```js - * const EventEmitter = require('events'); - * class MyEmitter extends EventEmitter {} * const myEmitter = new MyEmitter(); * * const callbackA = () => { @@ -778,10 +608,9 @@ declare module "events" { * * When a single function has been added as a handler multiple times for a single * event (as in the example below), `removeListener()` will remove the most - * recently added instance. In the example the `once('ping')` listener is removed: + * recently added instance. In the example the `once('ping')`listener is removed: * * ```js - * const EventEmitter = require('events'); * const ee = new EventEmitter(); * * function pong() { @@ -799,26 +628,12 @@ declare module "events" { * Returns a reference to the `EventEmitter`, so that calls can be chained. * @since v0.1.26 */ - removeListener>( - eventName: EventName, - listener: Listener, - ): this; - removeListener( - eventName: EventName, - listener: Listener, - ): this; + removeListener(eventName: Key, listener: Listener1): this; /** * Alias for `emitter.removeListener()`. * @since v10.0.0 */ - off>( - eventName: EventName, - listener: Listener, - ): this; - off( - eventName: EventName, - listener: Listener, - ): this; + off(eventName: Key, listener: Listener1): this; /** * Removes all listeners, or those of the specified `eventName`. * @@ -829,15 +644,12 @@ declare module "events" { * Returns a reference to the `EventEmitter`, so that calls can be chained. * @since v0.1.26 */ - /* eslint-disable @definitelytyped/no-unnecessary-generics */ - removeAllListeners>(eventName: EventName): this; - removeAllListeners(eventName?: EventName): this; - /* eslint-enable @definitelytyped/no-unnecessary-generics */ + removeAllListeners(event?: Key): this; /** * By default `EventEmitter`s will print a warning if more than `10` listeners are * added for a particular event. This is a useful default that helps finding * memory leaks. The `emitter.setMaxListeners()` method allows the limit to be - * modified for this specific `EventEmitter` instance. The value can be set to `Infinity` (or `0`) to indicate an unlimited number of listeners. + * modified for this specific `EventEmitter` instance. The value can be set to`Infinity` (or `0`) to indicate an unlimited number of listeners. * * Returns a reference to the `EventEmitter`, so that calls can be chained. * @since v0.3.5 @@ -861,18 +673,12 @@ declare module "events" { * ``` * @since v0.1.26 */ - listeners>( - eventName: EventName, - ): Array>; - listeners( - eventName: EventName, - ): Array>; + listeners(eventName: Key): Array>; /** * Returns a copy of the array of listeners for the event named `eventName`, * including any wrappers (such as those created by `.once()`). * * ```js - * const EventEmitter = require('events'); * const emitter = new EventEmitter(); * emitter.once('log', () => console.log('log once')); * @@ -897,14 +703,9 @@ declare module "events" { * ``` * @since v9.4.0 */ - rawListeners>( - eventName: EventName, - ): Array>; - rawListeners( - eventName: EventName, - ): Array>; + rawListeners(eventName: Key): Array>; /** - * Synchronously calls each of the listeners registered for the event named `eventName`, in the order they were registered, passing the supplied arguments + * Synchronously calls each of the listeners registered for the event named`eventName`, in the order they were registered, passing the supplied arguments * to each. * * Returns `true` if the event had listeners, `false` otherwise. @@ -943,35 +744,22 @@ declare module "events" { * ``` * @since v0.1.26 */ - emit>( - eventName: EventName, - ...args: Args - ): boolean; - emit( - eventName: EventName, - ...args: Args - ): boolean; + emit(eventName: Key, ...args: Args): boolean; /** - * Returns the number of listeners listening for the event named `eventName`. - * If `listener` is provided, it will return how many times the listener is found - * in the list of the listeners of the event. + * Returns the number of listeners listening to the event named `eventName`. + * + * If `listener` is provided, it will return how many times the listener + * is found in the list of the listeners of the event. * @since v3.2.0 * @param eventName The name of the event being listened for * @param listener The event handler function */ - listenerCount>( - eventName: EventName, - listener?: Listener, - ): number; - listenerCount( - eventName: EventName, - listener?: Listener, - ): number; + listenerCount(eventName: Key, listener?: Listener2): number; /** * Adds the `listener` function to the _beginning_ of the listeners array for the * event named `eventName`. No checks are made to see if the `listener` has - * already been added. Multiple calls passing the same combination of `eventName` - * and `listener` will result in the `listener` being added, and called, multiple times. + * already been added. Multiple calls passing the same combination of `eventName` and `listener` will result in the `listener` being added, and called, multiple + * times. * * ```js * server.prependListener('connection', (stream) => { @@ -984,14 +772,7 @@ declare module "events" { * @param eventName The name of the event. * @param listener The callback function */ - prependListener>( - eventName: EventName, - listener: Listener, - ): this; - prependListener( - eventName: EventName, - listener: Listener, - ): this; + prependListener(eventName: Key, listener: Listener1): this; /** * Adds a **one-time**`listener` function for the event named `eventName` to the _beginning_ of the listeners array. The next time `eventName` is triggered, this * listener is removed, and then invoked. @@ -1007,14 +788,7 @@ declare module "events" { * @param eventName The name of the event. * @param listener The callback function */ - prependOnceListener>( - eventName: EventName, - listener: Listener, - ): this; - prependOnceListener( - eventName: EventName, - listener: Listener, - ): this; + prependOnceListener(eventName: Key, listener: Listener1): this; /** * Returns an array listing the events for which the emitter has registered * listeners. The values in the array are strings or `Symbol`s. @@ -1033,7 +807,7 @@ declare module "events" { * ``` * @since v6.0.0 */ - eventNames(): Array<(string | symbol)> & Array>; + eventNames(): Array<(string | symbol) & Key2>; } } } diff --git a/types/node/v18/test/events.ts b/types/node/v18/test/events.ts index 17d7d7cafed50c..2471b3e1c5b08c 100644 --- a/types/node/v18/test/events.ts +++ b/types/node/v18/test/events.ts @@ -31,7 +31,7 @@ declare const any: any; result = emitter.getMaxListeners(); result = emitter.listenerCount(event); - const handler = () => {}; + const handler: Function = () => {}; result = emitter.listenerCount(event, handler); } diff --git a/types/node/v18/test/events_generic.ts b/types/node/v18/test/events_generic.ts index b8cb5f068da65f..ebc342451c75bc 100644 --- a/types/node/v18/test/events_generic.ts +++ b/types/node/v18/test/events_generic.ts @@ -110,17 +110,13 @@ declare const event5: "event5"; } { - let result1: Promise; - let result2: Promise; - let result3: Promise; - let result4: Promise; - let result5: Promise; - - result1 = events.once(emitter, event1); - result2 = events.once(emitter, event2); - result3 = events.once(emitter, event3); - result4 = events.once(emitter, event4); - result5 = events.once(emitter, event5); + let result: Promise; + + result = events.once(emitter, event1); + result = events.once(emitter, event2); + result = events.once(emitter, event3); + result = events.once(emitter, event4); + result = events.once(emitter, event5); emitter.emit("event1", "hello", 42); emitter.emit("event2", true); @@ -150,7 +146,7 @@ declare const event5: "event5"; } { - let result: Array; + let result: Array; result = emitter.eventNames(); } @@ -161,12 +157,12 @@ declare const event5: "event5"; ) : never; - function on1(event: K, listener: Listener): void { + function on1(event: K, listener: Listener): void { emitter.on(event, listener); } // eslint-disable-next-line @definitelytyped/no-unnecessary-generics - function on2(...args: Parameters>): void { + function on2(...args: Parameters>): void { emitter.on(...args); } @@ -208,6 +204,7 @@ declare const event5: "event5"; emitter.emit("abc", "hello", 123); // @ts-expect-error emitter.emit("abc", 123, false); + // @ts-expect-error emitter.emit("def", "hello", 123); } @@ -229,6 +226,7 @@ declare const event5: "event5"; emitter.emit(s1, "hello", 123); // @ts-expect-error emitter.emit(s1, 123, false); + // @ts-expect-error emitter.emit(s2, "hello", 123); } @@ -246,71 +244,6 @@ declare const event5: "event5"; emitter.emit(789, 123, false); // @ts-expect-error emitter.emit(s1, "hello", false); - emitter.emit(s2, "hello", false); -} - -{ - const promise1: Promise<[string, number]> = events.once(new events.EventEmitter(), "event1"); - const promise2: Promise<[boolean]> = events.once(new events.EventEmitter(), "event2"); - const promise3: Promise<[]> = events.once(new events.EventEmitter(), "event3"); - const promise4: Promise = events.once(new events.EventEmitter(), "event4"); - const promise5: Promise = events.once(new events.EventEmitter(), "event5"); - // @ts-expect-error - const promise6: Promise<[string, string]> = events.once(new events.EventEmitter(), "event1"); - const promise7: Promise = events.once(new events.EventEmitter(), "event"); - - const iterable1: NodeJS.AsyncIterator<[string, number]> = events.on(new events.EventEmitter(), "event1"); - const iterable2: NodeJS.AsyncIterator<[boolean]> = events.on(new events.EventEmitter(), "event2"); - const iterable3: NodeJS.AsyncIterator<[]> = events.on(new events.EventEmitter(), "event3"); - const iterable4: NodeJS.AsyncIterator = events.on(new events.EventEmitter(), "event4"); - const iterable5: NodeJS.AsyncIterator = events.on(new events.EventEmitter(), "event5"); // @ts-expect-error - const iterable6: NodeJS.AsyncIterator<[string, string]> = events.on(new events.EventEmitter(), "event1"); - const iterable7: NodeJS.AsyncIterator = events.on(new events.EventEmitter(), "event"); -} - -{ - function acceptsEventEmitterInterface(eventEmitter: NodeJS.EventEmitter) { - } - - function acceptsEventEmitterClass(eventEmitter: events.EventEmitter) { - } - - acceptsEventEmitterInterface(emitter); - acceptsEventEmitterClass(emitter); -} - -{ - class Extended extends events.EventEmitter {} - - class DoubleExtension extends Extended {} - - const extended = new Extended(); - const doubleExtended = new DoubleExtension(); - - events.on(extended, "event1"); // $ExpectType AsyncIterator<[string, number], any, any> - events.once(extended, "event1"); // $ExpectType Promise<[string, number]> - - events.on(extended, "unknown"); // $ExpectType AsyncIterator - events.once(extended, "unknown"); // $ExpectType Promise - - events.on(doubleExtended, "event1"); // $ExpectType AsyncIterator<[string, number], any, any> - events.once(doubleExtended, "event1"); // $ExpectType Promise<[string, number]> - - events.on(doubleExtended, "unknown"); // $ExpectType AsyncIterator - events.once(doubleExtended, "unknown"); // $ExpectType Promise - - extended.addListener(event1, (a: string, b: number | boolean): number => 1); - doubleExtended.addListener(event1, (a: string, b: number | boolean): number => 1); - // @ts-expect-error - extended.addListener(event1, (a: string, b: boolean): number => 1); - // @ts-expect-error - doubleExtended.addListener(event1, (a: string, b: boolean): number => 1); - - extended.emit("event1", "hello", 42); - doubleExtended.emit("event1", "hello", 42); - // @ts-expect-error - extended.emit("event1", 123); - // @ts-expect-error - doubleExtended.emit("event1", 123); + emitter.emit(s2, "hello", false); } diff --git a/types/node/v20/events.d.ts b/types/node/v20/events.d.ts index a47d27ea8dc7b6..250baa35aeaddc 100644 --- a/types/node/v20/events.d.ts +++ b/types/node/v20/events.d.ts @@ -34,7 +34,6 @@ * ``` * @see [source](https://github.com/nodejs/node/blob/v20.13.1/lib/events.js) */ - declare module "events" { import { AsyncResource, AsyncResourceOptions } from "node:async_hooks"; // NOTE: This class is in the docs but is **not actually exported** by Node. @@ -100,27 +99,23 @@ declare module "events" { */ lowWaterMark?: number | undefined; } - interface EventEmitter = {}> extends NodeJS.EventEmitter {} - type EventMap = Record; - type Args, EventName> = EventName extends keyof Events ? ( - | Events[EventName] - | (EventName extends keyof EventEmitter.EventEmitterBuiltInEventMap - ? EventEmitter.EventEmitterBuiltInEventMap[EventName] - : never) - ) - : (EventName extends keyof EventEmitter.EventEmitterBuiltInEventMap - ? EventEmitter.EventEmitterBuiltInEventMap[EventName] - : any[]); - type EventNames> = {} extends Events ? (string | symbol) - : (keyof Events | keyof EventEmitter.EventEmitterBuiltInEventMap); - type Listener, EventName> = EventName extends keyof Events ? - | ((...args: Events[EventName]) => void) - | (EventName extends keyof EventEmitter.EventEmitterBuiltInEventMap - ? (...args: EventEmitter.EventEmitterBuiltInEventMap[EventName]) => void - : never) - : (EventName extends keyof EventEmitter.EventEmitterBuiltInEventMap - ? (...args: EventEmitter.EventEmitterBuiltInEventMap[EventName]) => void - : (...args: any[]) => void); + interface EventEmitter = DefaultEventMap> extends NodeJS.EventEmitter {} + type EventMap = Record | DefaultEventMap; + type DefaultEventMap = [never]; + type AnyRest = [...args: any[]]; + type Args = T extends DefaultEventMap ? AnyRest : ( + K extends keyof T ? T[K] : never + ); + type Key = T extends DefaultEventMap ? string | symbol : K | keyof T; + type Key2 = T extends DefaultEventMap ? string | symbol : K & keyof T; + type Listener = T extends DefaultEventMap ? F : ( + K extends keyof T ? ( + T[K] extends unknown[] ? (...args: T[K]) => void : never + ) + : never + ); + type Listener1 = Listener void>; + type Listener2 = Listener; /** * The `EventEmitter` class is defined and exposed by the `node:events` module: @@ -135,20 +130,10 @@ declare module "events" { * It supports the following option: * @since v0.1.26 */ - class EventEmitter = {}> { + class EventEmitter = DefaultEventMap> { constructor(options?: EventEmitterOptions); - // This "property" is used to brand a specific instance of the EventEmitter class with its Event map, which is needed - // in order to infer the map if we have a chain like `class A extends EventEmitter<{}>` (or many levels deep) - // It is also marked as possibly undefined in order to allow something like `const t: NodeJS.EventEmitter<{}> = { };` - readonly #internalTypeOnlyBrand?: Events; - - [EventEmitter.captureRejectionSymbol]?>( - error: Error, - event: EventName, - ...args: Args - ): void; - [EventEmitter.captureRejectionSymbol]?(error: Error, event: string | symbol, ...args: any[]): void; + [EventEmitter.captureRejectionSymbol]?(error: Error, event: Key, ...args: Args): void; /** * Creates a `Promise` that is fulfilled when the `EventEmitter` emits the given @@ -229,11 +214,6 @@ declare module "events" { * ``` * @since v11.13.0, v10.16.0 */ - static once, EventName extends EventNames>( - emitter: EventEmitter, - eventName: EventName, - options?: StaticEventEmitterOptions, - ): Promise>; static once( emitter: NodeJS.EventEmitter, eventName: string | symbol, @@ -320,11 +300,6 @@ declare module "events" { * @since v13.6.0, v12.16.0 * @return An `AsyncIterator` that iterates `eventName` events emitted by the `emitter` */ - static on, EventName extends EventNames>( - emitter: EventEmitter, - eventName: EventName, - options?: StaticEventEmitterIteratorOptions, - ): NodeJS.AsyncIterator>; static on( emitter: NodeJS.EventEmitter, eventName: string | symbol, @@ -335,27 +310,6 @@ declare module "events" { eventName: string, options?: StaticEventEmitterIteratorOptions, ): NodeJS.AsyncIterator; - /** - * A class method that returns the number of listeners for the given `eventName` registered on the given `emitter`. - * - * ```js - * import { EventEmitter, listenerCount } from 'node:events'; - * - * const myEmitter = new EventEmitter(); - * myEmitter.on('event', () => {}); - * myEmitter.on('event', () => {}); - * console.log(listenerCount(myEmitter, 'event')); - * // Prints: 2 - * ``` - * @since v0.9.12 - * @deprecated Since v3.2.0 - Use `listenerCount` instead. - * @param emitter The emitter to query - * @param eventName The event name - */ - static listenerCount, EventName extends EventNames>( - emitter: EventEmitter, - eventName: EventName, - ): number; /** * A class method that returns the number of listeners for the given `eventName` registered on the given `emitter`. * @@ -401,14 +355,7 @@ declare module "events" { * ``` * @since v15.2.0, v14.17.0 */ - static getEventListeners, EventName extends EventNames>( - emitter: EventEmitter, - name: EventName, - ): Array>; - static getEventListeners( - emitter: EventTarget | NodeJS.EventEmitter, - name: string | symbol, - ): Function[]; + static getEventListeners(emitter: EventTarget | NodeJS.EventEmitter, name: string | symbol): Function[]; /** * Returns the currently set max amount of listeners. * @@ -638,37 +585,16 @@ declare module "events" { */ readonly asyncResource: EventEmitterReferencingAsyncResource; } - - export interface EventEmitterBuiltInEventMap { - newListener: [eventName: string | symbol, listener: Function]; - removeListener: [eventName: string | symbol, listener: Function]; - } } global { namespace NodeJS { - interface EventEmitter = {}> { - [EventEmitter.captureRejectionSymbol]?>( - error: Error, - event: EventName, - ...args: Args - ): void; - [EventEmitter.captureRejectionSymbol]?( - error: Error, - event: EventName, - ...args: Args - ): void; + interface EventEmitter = DefaultEventMap> { + [EventEmitter.captureRejectionSymbol]?(error: Error, event: Key, ...args: Args): void; /** * Alias for `emitter.on(eventName, listener)`. * @since v0.1.26 */ - addListener>( - eventName: EventName, - listener: Listener, - ): this; - addListener( - eventName: EventName, - listener: Listener, - ): this; + addListener(eventName: Key, listener: Listener1): this; /** * Adds the `listener` function to the end of the listeners array for the event * named `eventName`. No checks are made to see if the `listener` has already @@ -700,14 +626,7 @@ declare module "events" { * @param eventName The name of the event. * @param listener The callback function */ - on>( - eventName: EventName, - listener: Listener, - ): this; - on( - eventName: EventName, - listener: Listener, - ): this; + on(eventName: Key, listener: Listener1): this; /** * Adds a **one-time** `listener` function for the event named `eventName`. The * next time `eventName` is triggered, this listener is removed and then invoked. @@ -737,14 +656,7 @@ declare module "events" { * @param eventName The name of the event. * @param listener The callback function */ - once>( - eventName: EventName, - listener: Listener, - ): this; - once( - eventName: EventName, - listener: Listener, - ): this; + once(eventName: Key, listener: Listener1): this; /** * Removes the specified `listener` from the listener array for the event named `eventName`. * @@ -827,26 +739,12 @@ declare module "events" { * Returns a reference to the `EventEmitter`, so that calls can be chained. * @since v0.1.26 */ - removeListener>( - eventName: EventName, - listener: Listener, - ): this; - removeListener( - eventName: EventName, - listener: Listener, - ): this; + removeListener(eventName: Key, listener: Listener1): this; /** * Alias for `emitter.removeListener()`. * @since v10.0.0 */ - off>( - eventName: EventName, - listener: Listener, - ): this; - off( - eventName: EventName, - listener: Listener, - ): this; + off(eventName: Key, listener: Listener1): this; /** * Removes all listeners, or those of the specified `eventName`. * @@ -857,10 +755,7 @@ declare module "events" { * Returns a reference to the `EventEmitter`, so that calls can be chained. * @since v0.1.26 */ - /* eslint-disable @definitelytyped/no-unnecessary-generics */ - removeAllListeners>(eventName: EventName): this; - removeAllListeners(eventName?: EventName): this; - /* eslint-enable @definitelytyped/no-unnecessary-generics */ + removeAllListeners(eventName?: Key): this; /** * By default `EventEmitter`s will print a warning if more than `10` listeners are * added for a particular event. This is a useful default that helps finding @@ -889,12 +784,7 @@ declare module "events" { * ``` * @since v0.1.26 */ - listeners>( - eventName: EventName, - ): Array>; - listeners( - eventName: EventName, - ): Array>; + listeners(eventName: Key): Array>; /** * Returns a copy of the array of listeners for the event named `eventName`, * including any wrappers (such as those created by `.once()`). @@ -925,12 +815,7 @@ declare module "events" { * ``` * @since v9.4.0 */ - rawListeners>( - eventName: EventName, - ): Array>; - rawListeners( - eventName: EventName, - ): Array>; + rawListeners(eventName: Key): Array>; /** * Synchronously calls each of the listeners registered for the event named `eventName`, in the order they were registered, passing the supplied arguments * to each. @@ -971,14 +856,7 @@ declare module "events" { * ``` * @since v0.1.26 */ - emit>( - eventName: EventName, - ...args: Args - ): boolean; - emit( - eventName: EventName, - ...args: Args - ): boolean; + emit(eventName: Key, ...args: Args): boolean; /** * Returns the number of listeners listening for the event named `eventName`. * If `listener` is provided, it will return how many times the listener is found @@ -987,14 +865,7 @@ declare module "events" { * @param eventName The name of the event being listened for * @param listener The event handler function */ - listenerCount>( - eventName: EventName, - listener?: Listener, - ): number; - listenerCount( - eventName: EventName, - listener?: Listener, - ): number; + listenerCount(eventName: Key, listener?: Listener2): number; /** * Adds the `listener` function to the _beginning_ of the listeners array for the * event named `eventName`. No checks are made to see if the `listener` has @@ -1012,14 +883,7 @@ declare module "events" { * @param eventName The name of the event. * @param listener The callback function */ - prependListener>( - eventName: EventName, - listener: Listener, - ): this; - prependListener( - eventName: EventName, - listener: Listener, - ): this; + prependListener(eventName: Key, listener: Listener1): this; /** * Adds a **one-time**`listener` function for the event named `eventName` to the _beginning_ of the listeners array. The next time `eventName` is triggered, this * listener is removed, and then invoked. @@ -1035,14 +899,7 @@ declare module "events" { * @param eventName The name of the event. * @param listener The callback function */ - prependOnceListener>( - eventName: EventName, - listener: Listener, - ): this; - prependOnceListener( - eventName: EventName, - listener: Listener, - ): this; + prependOnceListener(eventName: Key, listener: Listener1): this; /** * Returns an array listing the events for which the emitter has registered * listeners. The values in the array are strings or `Symbol`s. @@ -1062,7 +919,7 @@ declare module "events" { * ``` * @since v6.0.0 */ - eventNames(): Array<(string | symbol)> & Array>; + eventNames(): Array<(string | symbol) & Key2>; } } } diff --git a/types/node/v20/test/events.ts b/types/node/v20/test/events.ts index ee3c21065b95e0..5ff88c63a06af5 100644 --- a/types/node/v20/test/events.ts +++ b/types/node/v20/test/events.ts @@ -31,7 +31,7 @@ declare const any: any; result = emitter.getMaxListeners(); result = emitter.listenerCount(event); - const handler = () => {}; + const handler: Function = () => {}; result = emitter.listenerCount(event, handler); } @@ -141,7 +141,7 @@ async function testEventTarget() { captureRejectionSymbol2 = events.captureRejectionSymbol; const emitter = new events.EventEmitter(); - emitter[events.captureRejectionSymbol] = (err: Error, name: string | symbol, ...args: any[]) => {}; + emitter[events.captureRejectionSymbol] = (err: Error, name: string, ...args: any[]) => {}; } { @@ -193,16 +193,16 @@ async function testEventTarget() { { class MyEmitter extends events.EventEmitter { - addListener(event: string | symbol, listener: () => void): this { + addListener(event: string, listener: () => void): this { return this; } - listeners(event: string | symbol): Array<() => void> { + listeners(event: string): Array<() => void> { return []; } - emit(event: string | symbol, ...args: any[]): boolean { + emit(event: string, ...args: any[]): boolean { return true; } - listenerCount(type: string | symbol): number { + listenerCount(type: string): number { return 0; } } diff --git a/types/node/v20/test/events_generic.ts b/types/node/v20/test/events_generic.ts index b8cb5f068da65f..ebc342451c75bc 100644 --- a/types/node/v20/test/events_generic.ts +++ b/types/node/v20/test/events_generic.ts @@ -110,17 +110,13 @@ declare const event5: "event5"; } { - let result1: Promise; - let result2: Promise; - let result3: Promise; - let result4: Promise; - let result5: Promise; - - result1 = events.once(emitter, event1); - result2 = events.once(emitter, event2); - result3 = events.once(emitter, event3); - result4 = events.once(emitter, event4); - result5 = events.once(emitter, event5); + let result: Promise; + + result = events.once(emitter, event1); + result = events.once(emitter, event2); + result = events.once(emitter, event3); + result = events.once(emitter, event4); + result = events.once(emitter, event5); emitter.emit("event1", "hello", 42); emitter.emit("event2", true); @@ -150,7 +146,7 @@ declare const event5: "event5"; } { - let result: Array; + let result: Array; result = emitter.eventNames(); } @@ -161,12 +157,12 @@ declare const event5: "event5"; ) : never; - function on1(event: K, listener: Listener): void { + function on1(event: K, listener: Listener): void { emitter.on(event, listener); } // eslint-disable-next-line @definitelytyped/no-unnecessary-generics - function on2(...args: Parameters>): void { + function on2(...args: Parameters>): void { emitter.on(...args); } @@ -208,6 +204,7 @@ declare const event5: "event5"; emitter.emit("abc", "hello", 123); // @ts-expect-error emitter.emit("abc", 123, false); + // @ts-expect-error emitter.emit("def", "hello", 123); } @@ -229,6 +226,7 @@ declare const event5: "event5"; emitter.emit(s1, "hello", 123); // @ts-expect-error emitter.emit(s1, 123, false); + // @ts-expect-error emitter.emit(s2, "hello", 123); } @@ -246,71 +244,6 @@ declare const event5: "event5"; emitter.emit(789, 123, false); // @ts-expect-error emitter.emit(s1, "hello", false); - emitter.emit(s2, "hello", false); -} - -{ - const promise1: Promise<[string, number]> = events.once(new events.EventEmitter(), "event1"); - const promise2: Promise<[boolean]> = events.once(new events.EventEmitter(), "event2"); - const promise3: Promise<[]> = events.once(new events.EventEmitter(), "event3"); - const promise4: Promise = events.once(new events.EventEmitter(), "event4"); - const promise5: Promise = events.once(new events.EventEmitter(), "event5"); - // @ts-expect-error - const promise6: Promise<[string, string]> = events.once(new events.EventEmitter(), "event1"); - const promise7: Promise = events.once(new events.EventEmitter(), "event"); - - const iterable1: NodeJS.AsyncIterator<[string, number]> = events.on(new events.EventEmitter(), "event1"); - const iterable2: NodeJS.AsyncIterator<[boolean]> = events.on(new events.EventEmitter(), "event2"); - const iterable3: NodeJS.AsyncIterator<[]> = events.on(new events.EventEmitter(), "event3"); - const iterable4: NodeJS.AsyncIterator = events.on(new events.EventEmitter(), "event4"); - const iterable5: NodeJS.AsyncIterator = events.on(new events.EventEmitter(), "event5"); // @ts-expect-error - const iterable6: NodeJS.AsyncIterator<[string, string]> = events.on(new events.EventEmitter(), "event1"); - const iterable7: NodeJS.AsyncIterator = events.on(new events.EventEmitter(), "event"); -} - -{ - function acceptsEventEmitterInterface(eventEmitter: NodeJS.EventEmitter) { - } - - function acceptsEventEmitterClass(eventEmitter: events.EventEmitter) { - } - - acceptsEventEmitterInterface(emitter); - acceptsEventEmitterClass(emitter); -} - -{ - class Extended extends events.EventEmitter {} - - class DoubleExtension extends Extended {} - - const extended = new Extended(); - const doubleExtended = new DoubleExtension(); - - events.on(extended, "event1"); // $ExpectType AsyncIterator<[string, number], any, any> - events.once(extended, "event1"); // $ExpectType Promise<[string, number]> - - events.on(extended, "unknown"); // $ExpectType AsyncIterator - events.once(extended, "unknown"); // $ExpectType Promise - - events.on(doubleExtended, "event1"); // $ExpectType AsyncIterator<[string, number], any, any> - events.once(doubleExtended, "event1"); // $ExpectType Promise<[string, number]> - - events.on(doubleExtended, "unknown"); // $ExpectType AsyncIterator - events.once(doubleExtended, "unknown"); // $ExpectType Promise - - extended.addListener(event1, (a: string, b: number | boolean): number => 1); - doubleExtended.addListener(event1, (a: string, b: number | boolean): number => 1); - // @ts-expect-error - extended.addListener(event1, (a: string, b: boolean): number => 1); - // @ts-expect-error - doubleExtended.addListener(event1, (a: string, b: boolean): number => 1); - - extended.emit("event1", "hello", 42); - doubleExtended.emit("event1", "hello", 42); - // @ts-expect-error - extended.emit("event1", 123); - // @ts-expect-error - doubleExtended.emit("event1", 123); + emitter.emit(s2, "hello", false); } diff --git a/types/opossum/opossum-tests.ts b/types/opossum/opossum-tests.ts index 903e1ac3de00f7..c962f758cb15be 100644 --- a/types/opossum/opossum-tests.ts +++ b/types/opossum/opossum-tests.ts @@ -142,7 +142,7 @@ const options: CircuitBreaker.Options = { resetTimeout: 30000, // After 30 seconds, try again. }; options.enableSnapshots; // $ExpectType boolean | undefined -options.rotateBucketController; // $ExpectType EventEmitter<{}> | undefined +options.rotateBucketController; // $ExpectType EventEmitter | undefined breaker = new CircuitBreaker(asyncFunctionThatCouldFail, options); breaker diff --git a/types/rdf-store-fs/rdf-store-fs-tests.ts b/types/rdf-store-fs/rdf-store-fs-tests.ts index a8c234a8cf6827..4ca59618ea65a9 100644 --- a/types/rdf-store-fs/rdf-store-fs-tests.ts +++ b/types/rdf-store-fs/rdf-store-fs-tests.ts @@ -45,20 +45,20 @@ function store_match() { function store_import() { const stream: Stream = {}; - // $ExpectType EventEmitter<{}> + // $ExpectType EventEmitter let imported = flatStore.import(stream); imported = flatStore.import(stream, { truncate: true }); } function store_remove() { const stream: Stream = {}; - // $ExpectType EventEmitter<{}> + // $ExpectType EventEmitter const event = flatStore.remove(stream); } function store_removeMatches() { const term: Term = {}; - // $ExpectType EventEmitter<{}> + // $ExpectType EventEmitter let event = flatStore.removeMatches(); event = flatStore.removeMatches(term); event = flatStore.removeMatches(term, term); @@ -68,7 +68,7 @@ function store_removeMatches() { function store_deleteGraph() { const graph: Quad_Graph = {}; - // $ExpectType EventEmitter<{}> + // $ExpectType EventEmitter const event = flatStore.deleteGraph(graph); } diff --git a/types/readable-stream/index.d.ts b/types/readable-stream/index.d.ts index 8494a42a9df4ea..60676de54f29ff 100644 --- a/types/readable-stream/index.d.ts +++ b/types/readable-stream/index.d.ts @@ -209,8 +209,10 @@ declare class _Readable extends NoAsyncDispose implements _IReadable { off(eventName: string | symbol, listener: (...args: any[]) => void): this; setMaxListeners(n: number): this; getMaxListeners(): number; - listeners(eventName: string | symbol): Array<(...args: any[]) => void>; - rawListeners(eventName: string | symbol): Array<(...args: any[]) => void>; + // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type + listeners(eventName: string | symbol): Function[]; + // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type + rawListeners(eventName: string | symbol): Function[]; listenerCount(eventName: string | symbol): number; eventNames(): Array; diff --git a/types/sane/index.d.ts b/types/sane/index.d.ts index 4d9d521d74e896..004cb1bc0c8944 100644 --- a/types/sane/index.d.ts +++ b/types/sane/index.d.ts @@ -80,7 +80,8 @@ declare class SaneWatcher extends EventEmitter { removeListener(event: "add" | "change", listener: (path: string, root: string, stat: Stats) => void): this; removeListener(event: "delete", listener: (path: string, root: string) => void): this; removeAllListeners(event?: EventType): this; - listeners(event: EventType): Array<(...args: any[]) => void>; + // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type + listeners(event: EventType): Function[]; emit(event: "ready"): boolean; emit(event: "error", error: Error): boolean; emit(event: "all", eventType: AllEventType, path: string, root: string, stat?: Stats): boolean; diff --git a/types/sse/sse-tests.ts b/types/sse/sse-tests.ts index 1de65f57b5f533..774c3dc854ba87 100644 --- a/types/sse/sse-tests.ts +++ b/types/sse/sse-tests.ts @@ -17,7 +17,7 @@ new SSE(expressApp, options); // $ExpectType SSE const sse = new SSE(expressApp); // $ExpectType SSE sse.handleRequest(expressApp.request, expressApp.response, "query"); // $ExpectType void sse.matchesPath("/sse", "/sse"); // $ExpectType boolean -sse.server; // $ExpectType EventEmitter<{}> +sse.server; // $ExpectType EventEmitter SSE.Client; // $ExpectType typeof Client const sseClient = new SSE.Client(expressApp.request, expressApp.response); // $ExpectType Client diff --git a/types/steam/index.d.ts b/types/steam/index.d.ts index 3021e71d8f4082..ceac66071677c0 100644 --- a/types/steam/index.d.ts +++ b/types/steam/index.d.ts @@ -44,5 +44,17 @@ declare namespace Steam { setPersonaState(state: EPersonaState): void; setPersonaName(name: string): void; + + // Event emitter + addListener(event: string, listener: Function): this; + on(event: string, listener: Function): this; + once(event: string, listener: Function): this; + removeListener(event: string, listener: Function): this; + removeAllListeners(event?: string): this; + setMaxListeners(n: number): this; + getMaxListeners(): number; + listeners(event: string): Function[]; + emit(event: string, ...args: any[]): boolean; + listenerCount(type: string): number; } } diff --git a/types/twitter/twitter-tests.ts b/types/twitter/twitter-tests.ts index 23c288fbddf5d5..b6aa9b1d710b4b 100644 --- a/types/twitter/twitter-tests.ts +++ b/types/twitter/twitter-tests.ts @@ -53,7 +53,7 @@ stream.on("error", error => { }); client.stream("statuses/filter", { track: "javascript" }, stream => { - // $ExpectType EventEmitter<{}> + // $ExpectType EventEmitter stream; stream.on("data", (event: any) => { @@ -65,6 +65,6 @@ client.stream("statuses/filter", { track: "javascript" }, stream => { }); }); client.stream("statuses/filter", stream => { - // $ExpectType EventEmitter<{}> + // $ExpectType EventEmitter stream; }); diff --git a/types/umzug/index.d.ts b/types/umzug/index.d.ts index 93cac40d864bf1..f2ef58d0841fd4 100644 --- a/types/umzug/index.d.ts +++ b/types/umzug/index.d.ts @@ -231,15 +231,15 @@ declare namespace umzug { on( eventName: "migrating" | "reverting" | "migrated" | "reverted", - cb: (name: string, migration: Migration) => void, + cb?: (name: string, migration: Migration) => void, ): this; addListener( eventName: "migrating" | "reverting" | "migrated" | "reverted", - cb: (name: string, migration: Migration) => void, + cb?: (name: string, migration: Migration) => void, ): this; removeListener( eventName: "migrating" | "reverting" | "migrated" | "reverted", - cb: (name: string, migration: Migration) => void, + cb?: (name: string, migration: Migration) => void, ): this; } diff --git a/types/xml-flow/xml-flow-tests.ts b/types/xml-flow/xml-flow-tests.ts index b5608d0e817966..2c5f397e4f477c 100644 --- a/types/xml-flow/xml-flow-tests.ts +++ b/types/xml-flow/xml-flow-tests.ts @@ -8,7 +8,7 @@ fs.writeFileSync("./test.xml", "texttext +// $ExpectType EventEmitter const myFlow = flow(readStreamOne); const myOptions = { @@ -22,7 +22,7 @@ const myOptions = { strict: true, }; -// $ExpectType EventEmitter<{}> +// $ExpectType EventEmitter const myFlowWithOptions = flow(readStreamTwo, myOptions); // Create object to xml-ise