From 36239af714c5bdd21ed41c9837cfbf8448e40497 Mon Sep 17 00:00:00 2001 From: spencercap Date: Tue, 12 Oct 2021 00:14:36 +0100 Subject: [PATCH 1/3] added proposed solution for variable event names from: https://github.com/andywer/typed-emitter/issues/15 --- index.d.ts | 52 +++++++++++++++++++++++++++++++++------------------- package.json | 2 +- 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/index.d.ts b/index.d.ts index 6b0f0b4..3f2f43b 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,6 +1,19 @@ +// export type Arguments = [T] extends [(...args: infer U) => any] +// ? U +// : [T] extends [void] ? [] : [T] + +// variable name support export type Arguments = [T] extends [(...args: infer U) => any] - ? U - : [T] extends [void] ? [] : [T] + ? U + : [T] extends [void] + ? [] + : [T]; +type EventFunction = (...args: any[]) => void; +type EmitterEvents = EmitterEvent; +type EmitterEvent = { + name: Name; + args: Arguments; +}; /** * Type-safe event emitter. @@ -20,25 +33,26 @@ export type Arguments = [T] extends [(...args: infer U) => any] * * myEmitter.emit("error", "x") // <- Will catch this type error */ -interface TypedEventEmitter { - addListener (event: E, listener: Events[E]): this - on (event: E, listener: Events[E]): this - once (event: E, listener: Events[E]): this - prependListener (event: E, listener: Events[E]): this - prependOnceListener (event: E, listener: Events[E]): this +interface TypedEventEmitter { + addListener(event: E, listener: Events[E]): this; + on(event: E, listener: Events[E]): this; + once(event: E, listener: Events[E]): this; + prependListener(event: E, listener: Events[E]): this; + prependOnceListener(event: E, listener: Events[E]): this; - off(event: E, listener: Events[E]): this - removeAllListeners (event?: E): this - removeListener (event: E, listener: Events[E]): this + off(event: E, listener: Events[E]): this; + removeAllListeners(event?: E): this; + removeListener(event: E, listener: Events[E]): this; - emit (event: E, ...args: Arguments): boolean - eventNames (): (keyof Events | string | symbol)[] - rawListeners (event: E): Function[] - listeners (event: E): Function[] - listenerCount (event: E): number + // emit (event: E, ...args: Arguments): boolean + emit(name: E['name'], ...args: E['args']): this; + eventNames(): (keyof Events | string | symbol)[]; + rawListeners(event: E): Function[]; + listeners(event: E): Function[]; + listenerCount(event: E): number; - getMaxListeners (): number - setMaxListeners (maxListeners: number): this + getMaxListeners(): number; + setMaxListeners(maxListeners: number): this; } -export default TypedEventEmitter +export default TypedEventEmitter; diff --git a/package.json b/package.json index d39734e..990200e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typed-emitter", - "version": "1.3.1", + "version": "1.3.2", "license": "MIT", "description": "Strictly typed event emitter interface for TypeScript 3.", "author": "Andy Wermke (https://github.com/andywer)", From 3da38d5dd4a908cb89e8c3d94972b3738605335a Mon Sep 17 00:00:00 2001 From: spencercap Date: Tue, 12 Oct 2021 00:17:54 +0100 Subject: [PATCH 2/3] added exports --- index.d.ts | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/index.d.ts b/index.d.ts index 3f2f43b..5a9520b 100644 --- a/index.d.ts +++ b/index.d.ts @@ -8,9 +8,9 @@ export type Arguments = [T] extends [(...args: infer U) => any] : [T] extends [void] ? [] : [T]; -type EventFunction = (...args: any[]) => void; -type EmitterEvents = EmitterEvent; -type EmitterEvent = { +export type EventFunction = (...args: any[]) => void; +export type EmitterEvents = EmitterEvent; +export type EmitterEvent = { name: Name; args: Arguments; }; diff --git a/package.json b/package.json index 990200e..ac662e8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typed-emitter", - "version": "1.3.2", + "version": "1.3.3", "license": "MIT", "description": "Strictly typed event emitter interface for TypeScript 3.", "author": "Andy Wermke (https://github.com/andywer)", From a0fee99f7d1be2ea38d9d399df79d2d42d2d6f46 Mon Sep 17 00:00:00 2001 From: spencercap Date: Tue, 12 Oct 2021 00:52:50 +0100 Subject: [PATCH 3/3] cleaned up --- index.d.ts | 27 ++++++++++++++------------- package.json | 2 +- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/index.d.ts b/index.d.ts index 5a9520b..152c0ee 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,13 +1,9 @@ -// export type Arguments = [T] extends [(...args: infer U) => any] -// ? U -// : [T] extends [void] ? [] : [T] - -// variable name support export type Arguments = [T] extends [(...args: infer U) => any] ? U : [T] extends [void] ? [] : [T]; + export type EventFunction = (...args: any[]) => void; export type EmitterEvents = EmitterEvent; export type EmitterEvent = { @@ -20,20 +16,26 @@ export type EmitterEvent = { * * Use it like this: * - * interface MyEvents { - * error: (error: Error) => void - * message: (from: string, content: string) => void - * } + * type DynamicEvents = + * | EmitterEvent<'ping', () => void> + * | EmitterEvent<'message', (from: string, content: string) => void> + * | EmmiterEvents<'error': (error: Error) => void> + * | EmitterEvent<`foo:${string}`, (size: number, strict: boolean) => void> + * | EmitterEvent<`bar:${string}`, (force: boolean) => void>; * - * const myEmitter = new EventEmitter() as TypedEmitter + * const myEmitter = new EventEmitter() as TypedEmitter * * myEmitter.on("message", (from, content) => { * // ... * }) * * myEmitter.emit("error", "x") // <- Will catch this type error + * + * myEmitter.emit("foo:1", 2, false) // dynamic/variable event names work + * myEmitter.emit(`foo:${'456'}`, 2, false) + * */ -interface TypedEventEmitter { +export interface TypedEventEmitter { addListener(event: E, listener: Events[E]): this; on(event: E, listener: Events[E]): this; once(event: E, listener: Events[E]): this; @@ -44,8 +46,7 @@ interface TypedEventEmitter { removeAllListeners(event?: E): this; removeListener(event: E, listener: Events[E]): this; - // emit (event: E, ...args: Arguments): boolean - emit(name: E['name'], ...args: E['args']): this; + emit(name: E['name'], ...args: E['args']): boolean; eventNames(): (keyof Events | string | symbol)[]; rawListeners(event: E): Function[]; listeners(event: E): Function[]; diff --git a/package.json b/package.json index ac662e8..f1afd23 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typed-emitter", - "version": "1.3.3", + "version": "1.3.4", "license": "MIT", "description": "Strictly typed event emitter interface for TypeScript 3.", "author": "Andy Wermke (https://github.com/andywer)",