1.0.4 • Published 2 years ago
nest-typed-event-emitter v1.0.4
Nest Typed Event Emitter
Why
The default NestJS event emitter system does not directly support strict hinting for events. This package aims to add minimal support for having type-hinted events, with strict typing if desired.
How
First, define an interface for your events
// Your Event Map, with EventName => Types
export interface EventMap {
purchase: number;
paid: number;
}
Next, use the package to create listeners and emitters that wrap the normal NestJS entities.
import { IEventEmitter, createTypedListener } from "nest-typed-event-emitter";
// API to define the typed emitters
export type MyEventEmitter = IEventEmitter<EventMap>;
// Pass true to the second type parameter to make the emitters strict
export type MyStrictEventEmitter = IEventEmitter<EventMap, true>;
// API to define the typed listeners
const MyListener = createTypedListener<EventMap>();
// Pass true to the second type parameter to make the listeners strict
const MyStrictListener = createTypedListener<EventMap, true>();
Next, use the listeners you defined in place of the usual @OnEvent()
.
// Listener class
class Listeners {
/**
* This will type hint, but allow any value to be passed
*/
@MyListener("paid") // allowed
@MyListener("paidasdf") //allowed
public onSleepAdded(event: EventMap["paid"]) {}
/**
* This will type hint and forbid values not in the event map.
*/
@MyStrictListener("purchasef") // error
@MyStrictListener("purchase") // allowed
public onSleepAddedStrict(event: EventMap["purchase"]) {}
}
Finally, use the @InjectEventEmitter()
decorator to get access to the emitter.
You can then annotate it with the custom event emitter type you made in the
second part.
import { Injectable } from "@nestjs/common";
import { InjectEventEmitter } from "nest-typed-event-emitter";
// Emitter class
@Injectable()
class Service {
constructor(
@InjectEventEmitter() private readonly emitter: MyEventEmitter,
@InjectEventEmitter() private readonly strictEmitter: MyStrictEventEmitter
) {}
onPurchase() {
this.emitter.emit("purchase", 4); // allowed
this.emitter.emit("something-else", 12); //allowed
this.emitter.emit("purchase", "12"); //allowed
this.strictEmitter.emit("paid", 5); //allowed
this.strictEmitter.emit("ashjknfl", 34); //error
this.strictEmitter.emit("paid", "34"); //error
}
}
Remember to add the normal NestJS event emitter module into your app, i.e.
import { Module } from "@nestjs/common";
import { EventEmitterModule } from "@nestjs/event-emitter";
@Module({
imports: [EventEmitterModule.forRoot()],
controllers: [],
providers: [],
})
export class AppModule {}