@jartreg/typed-events
TypeScript icon, indicating that this package has built-in type declarations

1.1.0 • Public • Published

Typed Events

Build Status Code Coverage License

Type-safe events for TypeScript, either predefined or based on tag types

Features

Usage

EventEmitter

EventEmitter allows you to use events defined in a type definition.

Define the events:

type EventTypes = {
    "greet": (who: string) => Promise<void> | void,
    "other-event": (something: number) => Promise<void> | void
};

Instantiate or extend EventEmitter and specify the defined events:

const emitter = new EventEmitter<EventTypes>();

// OR

class SomeClass extends EventEmitter<EventTypes> {
    // ...
}

const someObject = new SomeClass();

Use the emitter and enjoy getting suggestions from your editor:

emitter.on("greet", (who) => {
    console.log("Hello " + who + "!");
});

emitter.emit("greet", "World");

EventBus

EventBus uses tag types to put type information into strings. It allows you to use any event on any EventBus, still providing type information for parameters. However, since the events are distinguished by strings at runtime, their names should be unique.

Define event types:

const GreetEvent = "greet" as EventType<(who: string) => Promise<void> | void>;

Instantiate or extend EventBus:

const bus = new EventBus();

// OR

class SomeClass extends EventBus {
    // ...
}

const someObject = new SomeClass();

Use it:

bus.on(GreetEvent, (who) => {
    console.log("Hello " + who + "!");
});

bus.emit(GreetEvent, "World");

Avoid name collisions

Since events are distinguished by the string assigned to their constant, different event types identified by the same string will still compile but might lead to unexpected behaviour at runtime:

// Two events with the same name, but different types:
const FunctionEvent = "some-event" as EventType<(cb: () => void)) => Promise<void> | void>;
const StringEvent = "some-event" as EventType<(arg: string) => Promise<void> | void>;

const bus = new EventBus();

// A listener expecting a function
bus.on(FunctionEvent, (cb: () => void)) => {
    // something...
    cb();
});

// Emitting the event with a string as the argument
bus.emit(StringEvent, "try calling me!");

Will result in:

TypeError: "string" is not a function

Asynchronous events

To wait for asynchronous event listeners, make them return a promise and use emitAsync when emitting the event:

// using async-await:
emitter.on("some-event", async () => {
    await somethingAsync();
});


// inside of an async function:

// wait for all listeners to complete
await emitter.emitAsync("some-event");

Removing listeners

Listeners can be removed by either using off or or the function returned by on and once.

Using off:

const listener () => {
    // something
};

emitter.on("some-event", listener);

// remove the listener:
emitter.off("some-event", listener);

Using the returned function:

const removeListener = emitter.on("some-event", () => {
    // something
});

// remove the listener:
removeListener();

Package Sidebar

Install

npm i @jartreg/typed-events

Weekly Downloads

0

Version

1.1.0

License

MIT

Unpacked Size

16.2 kB

Total Files

18

Last publish

Collaborators

  • jartreg