diff --git a/packages/lib/browser.ts b/packages/lib/browser.ts index 9e06d1db..5c430809 100644 --- a/packages/lib/browser.ts +++ b/packages/lib/browser.ts @@ -14,3 +14,4 @@ export * from "./src/subscriptions"; export { default as ExponentialBackoff } from "./src/ExponentialBackoff"; export { default as RateLimiter } from "./src/RateLimiter"; +export { default as TypedEventEmitter } from "./src/TypedEventEmitter"; diff --git a/packages/lib/index.ts b/packages/lib/index.ts index d6385d7c..508b900c 100644 --- a/packages/lib/index.ts +++ b/packages/lib/index.ts @@ -31,3 +31,4 @@ export * from "./src/subscriptions"; export { default as ExponentialBackoff } from "./src/ExponentialBackoff"; export { default as ModStore } from "./src/ModStore"; export { default as RateLimiter } from "./src/RateLimiter"; +export { default as TypedEventEmitter } from "./src/TypedEventEmitter"; diff --git a/packages/lib/src/ModStore.ts b/packages/lib/src/ModStore.ts index 83cb0167..8240d8f5 100644 --- a/packages/lib/src/ModStore.ts +++ b/packages/lib/src/ModStore.ts @@ -2,17 +2,7 @@ import fs from "fs-extra"; import path from "path"; import { logger } from "./logging"; import { ModInfo } from "./data"; -import EventEmitter from "events"; - -abstract class TypedEventEmitter< - Keys extends string, - Events extends Record void>, -> extends EventEmitter { - declare ["on"]: (event: E, listener: Events[E]) => this; - declare ["off"]: (event: E, listener: Events[E]) => this; - declare ["once"]: (event: E, listener: Events[E]) => this; - declare ["emit"]: (event: E, ...args: Parameters) => boolean; -} +import TypedEventEmitter from "./TypedEventEmitter"; export interface ModStoreEvents { /** A stored mod was created, updated or deleted */ diff --git a/packages/lib/src/TypedEventEmitter.ts b/packages/lib/src/TypedEventEmitter.ts new file mode 100644 index 00000000..206282e8 --- /dev/null +++ b/packages/lib/src/TypedEventEmitter.ts @@ -0,0 +1,27 @@ +import EventEmitter from "events"; + +/** + * Type checked version of EventEmitter + * + * @example + * ```ts + * interface Events { + * "foo": (a: number, b: number) => void, + * "bar": (spam: string) => void, + * } + * + * class Emitter extends TypedEventEmitter {} + * + * const e = new Emitter(); + * e.emit("foo", 1, 2) // type checked arguments + * ``` + */ +export default abstract class TypedEventEmitter< + Keys extends string, + Events extends Record void>, +> extends EventEmitter { + declare ["on"]: (event: E, listener: Events[E]) => this; + declare ["off"]: (event: E, listener: Events[E]) => this; + declare ["once"]: (event: E, listener: Events[E]) => this; + declare ["emit"]: (event: E, ...args: Parameters) => boolean; +}