{"id":12216,"library":"typed-emitter","title":"Strictly Typed Event Emitter Interface","description":"Typed-emitter is a lightweight TypeScript-only package (zero runtime bytes) that provides a strictly typed interface for event emitters. It is currently stable at version 2.1.0, receiving minor updates for bug fixes and feature enhancements, with occasional breaking changes primarily around type constraints or specific integration points like RxJS. Unlike `@types/node` which offers loose typings, or `eventemitter3` which lacks strong argument typing, typed-emitter allows developers to define a precise `EventMap` for their emitter instances. This enables compile-time verification of event names and listener argument signatures, preventing common runtime errors. It's designed to be used with existing `EventEmitter` implementations, such as Node.js's built-in `events` module or browser-based alternatives, without providing its own implementation.","status":"active","version":"2.1.0","language":"javascript","source_language":"en","source_url":"https://github.com/andywer/typed-emitter","tags":["javascript","event","emitter","typescript","interface"],"install":[{"cmd":"npm install typed-emitter","lang":"bash","label":"npm"},{"cmd":"yarn add typed-emitter","lang":"bash","label":"yarn"},{"cmd":"pnpm add typed-emitter","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"TypedEmitter is a default export.","wrong":"import { TypedEmitter } from 'typed-emitter'","symbol":"TypedEmitter","correct":"import TypedEmitter from 'typed-emitter'"},{"note":"The FromEvent interface for RxJS compatibility is exported from a subpath.","wrong":"import { FromEvent } from 'typed-emitter'","symbol":"FromEvent","correct":"import { FromEvent } from 'typed-emitter/rxjs'"},{"note":"Arguments is a named type export, useful for extracting listener parameter types.","wrong":"import Arguments from 'typed-emitter'","symbol":"Arguments","correct":"import { Arguments } from 'typed-emitter'"}],"quickstart":{"code":"import EventEmitter from \"events\";\nimport TypedEmitter from \"typed-emitter\";\n\ntype MessageEvents = {\n  error: (error: Error) => void;\n  message: (body: string, from: string) => void;\n  statusUpdate: (status: 'online' | 'offline') => void;\n};\n\nconst messageEmitter = new EventEmitter() as TypedEmitter<MessageEvents>;\n\n// Good: TypeScript validates event name and argument types\nmessageEmitter.emit(\"message\", \"Hi there!\", \"no-reply@test.com\");\nmessageEmitter.emit(\"statusUpdate\", \"online\");\n\n// TypeScript will catch type mistakes\n// @ts-expect-error Argument of type 'boolean' is not assignable to parameter of type 'string'.\nmessageEmitter.emit(\"message\", \"Hi there!\", true);\n// @ts-expect-error Argument of type 'string' is not assignable to parameter of type '\"online\" | \"offline\"'.\nmessageEmitter.emit(\"statusUpdate\", \"connecting\");\n\n// Good: Type-safe listener registration\nmessageEmitter.on(\"error\", (error: Error) => { console.error(error.message); });\n\n// TypeScript will catch mistakes in listener signatures\n// @ts-expect-error Argument of type 'string' is not assignable to parameter of type 'Error'.\nmessageEmitter.on(\"error\", (error: string) => { /* ... */ });\n\nconsole.log('Typed emitter setup successfully.');\n// To prevent process from exiting immediately in Node.js\nsetInterval(() => {}, 1000);","lang":"typescript","description":"Demonstrates defining event map types and applying them to a standard Node.js EventEmitter, showcasing compile-time type checking for `emit` and `on` calls."},"warnings":[{"fix":"Ensure all properties within your `EventMap` type are defined as functions (e.g., `(arg1: Type, arg2: Type) => void`).","message":"Since v2.0.0, the `TypedEmitter` generic type parameter `Events` is strictly constrained to `EventMap` (`{ [key: string]: (...args: any[]) => void }`). Your event map types must conform to this structure, where all properties are functions.","severity":"breaking","affected_versions":">=2.0.0"},{"fix":"Import `FromEvent` from `typed-emitter/rxjs` and cast `rxjs.fromEvent` to it: `import { fromEvent as rxFromEvent } from \"rxjs\"; import { FromEvent } from \"typed-emitter/rxjs\"; const fromEvent = rxFromEvent as FromEvent;`","message":"With v2.1.0, a new `TypedEmitter` interface for RxJS compatibility was introduced, exported from `typed-emitter/rxjs`. If you were previously using custom workarounds or older patterns for RxJS `fromEvent` type inference, you may need to update your imports and usage to leverage the new `FromEvent` type.","severity":"breaking","affected_versions":">=2.1.0"},{"fix":"Upgrade to `typed-emitter` v1.4.0 or newer to ensure correct package resolution and avoid potential build issues.","message":"Prior to v1.4.0, the `package.json` `main` field incorrectly pointed to a TypeScript `.ts` file instead of the compiled JavaScript. While fixed in v1.4.0, older versions might cause resolution issues, build failures, or unexpected behavior in bundlers or environments that don't correctly process `.ts` files directly as a main entry point.","severity":"gotcha","affected_versions":"<1.4.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Adjust the listener function signature (parameter types) to precisely match the `EventMap` definition for the corresponding event.","cause":"An event listener function's parameter type does not match the type defined in the `EventMap` for that event.","error":"Argument of type 'string' is not assignable to parameter of type 'Error'."},{"fix":"Add the desired event name and its corresponding listener signature to your `EventMap` type definition.","cause":"Attempting to emit or listen to an event name that has not been explicitly defined in the `EventMap` provided to `TypedEmitter`.","error":"Property 'myUndefinedEvent' does not exist on type 'TypedEmitter<MyEventMap>'."},{"fix":"Ensure that every property (event name) in your `EventMap` is defined as a function type (e.g., `eventName: (arg1: Type) => void`).","cause":"Your custom event map type contains properties that are not functions, violating the `EventMap` constraint introduced in v2.0.0.","error":"Type 'MyCustomEventMap' does not satisfy the constraint '{ [key: string]: (...args: any[]) => void; }'. Type 'MyCustomEventMap' is not assignable to type '{ [key: string]: (...args: any[]) => void; }'. Property 'invalidKey' is incompatible with index signature. Type 'string' is not assignable to type '(...args: any[]) => void'."}],"ecosystem":"npm"}