Skip to content
Vitaly Tomilov edited this page Oct 1, 2024 · 66 revisions

If you are exposing events from a reusable library or component, and want to limit clients to receiving events only, you can make use of the generic EventConsumer class provided with the library.

Class EventConsumer encapsulates an event object, to hide methods emit and cancelAll physically, so even a JavaScript client can't access those. But if you only care about TypeScript type checking, then you can instead define your own EventConsumer, via TypeScript's standard Omit helper:

type EventConsumer<T = unknown, E extends SubEvent<T> = SubEvent<T>>
                   = Omit<E, 'emit' | 'cancelAll'>;

The EventConsumer example then would be updated into the following:

class MyComponent {

    private event: SubEvent<string> = new SubEvent(); // internal, send-receive event

    get safeEvent() {
        // clients won't have access to methods "emit" and "cancelAll",
        // unless they simply re-cast the type.
        return this.event as EventConsumer<string>;
    }
}

As per the comments in the code, with this approach clients can still do (safeEvent as any).emit(), and this is why use of the pre-defined EventConsumer class is a safer option.

However, if you want to expose an event class derived from SubEvent, with additional methods available to the client, you cannot do it via pre-defined EventConsumer, because it is non-extendable, while the Omit approach allows it. Those are the cons and pros to consider.

Clone this wiki locally