• Stars
    star
    271
  • Rank 151,717 (Top 3 %)
  • Language
    TypeScript
  • Created almost 7 years ago
  • Updated over 3 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A type-only library for strongly typing any event emitter

Typed Event Emitter

NOTE: REQUIRES TYPESCRIPT 3.0

A TypeScript library for strongly typed event emitters in 0 kB. Declare events using a simple interface mapping event names to their payloads to get stricter versions of emit, on, and other common EventEmitter APIs. Works with any kind of EventEmitter.

Installation

npm i strict-event-emitter-types

Example

import StrictEventEmitter from 'strict-event-emitter-types';

// define your events
interface Events {
  request: (request: Request, response: Response) => void;
  done: void;
}

// grab an event emitter
import { EventEmitter } from 'events';

// Create strict event emitter types
let ee: StrictEventEmitter<EventEmitter, Events> = new EventEmitter;

// now enjoy your strongly typed EventEmitter API!🎉

ee.on('request', (r, resp) => ... );
// r and resp are contextually typed to Request and Response

ee.on('somethingElse');
// Error: unknown event

ee.on('done', x => x);
// Error: The 'done' event does not have a payload

ee.emit('request', new Request());
// Error: missing event payload (the response)

ee.emit('request', new Request(), false);
// Error: incorrect payload type

Usage

Event Records

Event records are interfaces or object types that map event names to the event's payload types. In the following example, three events are declared:

interface Events {
  req: (request: Request, response: Response) => void;
  done: void;
  conn: Connection;
}

Each event shows one of three ways to type the event payloads:

  1. Function type: Parameters are the event payload. The return type is ignored.
  2. void: A shortcut for an event with no payload, i.e. () => void
  3. Anything else: A shortcut for an event with one payload, for example (p: number) => void can be written as just number.

StrictEventEmitter<TEmitterType, TEventRecord, TEmitRecord>

The default export. A generic type that takes three type parameters:

  1. TEmitterType: Your EventEmitter type (e.g. node's EventEmitter or socket.io socket)
  2. TEventRecord: A type mapping event names to event payloads
  3. TEmitRecord: Optionally, a similar type mapping things you can emit.

The third parameter is handy when typing web sockets where client and server can listen to and emit different events. For example, if you are using socket.io:

// create types representing the server side and client
// side sockets
export type ServerSocket =
  StrictEventEmitter<SocketIO.Socket, EventsFromServer, EventsFromClient>;
export type ClientSocket =
  StrictEventEmitter<SocketIOClient.Socket, EventsFromClient, EventsFromServer>;

// elsewhere on server
let serverSocket: ServerSocket = new SocketIO.Socket();
serverSocket.on(/* only events that are sent from the client are allowed */, ...)
serverSocket.emit(/* only events that are emitted from the server are allowed */, ...)

// elsewhere on client
let clientSocket: ClientSocket = new SocketIOClient.Socket();
clientSocket.on(/* only events that are sent from the server are allowed */, ...)
clientSocket.emit(/* only events that are emitted from the client are allowed */, ...)
Usage with Subclasses

To subclass an EventEmitter you need to cast the base EventEmitter to the strict EventEmitter before extending:

type MyEmitter = StrictEventEmitter<EventEmitter, Events>;

class MyEventEmitter extends (EventEmitter as { new(): MyEmitter }) {
  doEmit() {
    this.emit(...); // strict
  }
}

StrictBroadcast<TStrictEventEmitter>

A type for a function which takes (and strictly checks) an emit event and a payload. TStrictEventEmitter is the event emitter type instantiated from StrictEventEmitter.

Useful for broadcast abstractions. It is not possible to contextually type assigments to this type, so your declarations will look something like this:

import { StrictBroadcast } from 'strict-event-emitter-types';

const broadcast: StrictBroadcast<ServerSocket> = function(
  event: string,
  payload?: any
) {
  // ...
};

Note that the loose types for event and payload only apply inside the broadcast function (consumers will see a much stricter signature). Declaring more precise parameter types or narrowing using type guards would allow strongly-typed dispatching to emitters.

More Repositories

1

eshost-cli

Run ECMAScript code uniformly across any ECMAScript host
JavaScript
194
star
2

redmine-status-updates

A plugin for Redmine that allows users to create little status updates on a per-project basis ala Twitter.
Ruby
50
star
3

tcq

TypeScript
38
star
4

reddit

An interface to the Reddit API
Ruby
26
star
5

armdsl

TypeScript
16
star
6

ecmascript

ECMAScript in HTML
JavaScript
12
star
7

constant-contact-ruby

Interface with the Constant Contact api
Ruby
10
star
8

httpclient

HTTPClient mirror with fixes and such
Ruby
9
star
9

blimlimb

blimLimb, the travelling IRC bot troupe, running on yail
Ruby
8
star
10

when-is-tc39

The code for http://whenistc39.com
JavaScript
4
star
11

ghe

A GitHub Events Dashboard
TypeScript
3
star
12

test262-compiler

Compiles a test262 test into an eshost-runnable script
JavaScript
3
star
13

headless-arrows

Proposal for headless (parameter-less) arrows for ECMAScript
HTML
3
star
14

cadl-e2e-demo

code to cloud in ten minutes with Cadl
TypeScript
2
star
15

trl.sn

2
star
16

my-emitter2

TypeScript
2
star
17

cadl-data-store

TypeScript
2
star
18

typespec-oas-express

Starter for building an express app using TypeSpec
TypeScript
2
star
19

tcq2

JavaScript
1
star
20

unicode-preso

JavaScript
1
star
21

typespec-validation

Validation decorators for TypeSpec
TypeScript
1
star
22

openai-in-typespec

OpenAI's service described using TypeSpec
1
star
23

delme

1
star
24

cadl-json-schema

Tools for working with JSON Schema and Cadl
TypeScript
1
star
25

ecmascript-static-types

Strawman for adding static types to ECMAScript
1
star
26

stream-bifurcate

Bifurcate (fork) a stream into multiple distributaries
JavaScript
1
star
27

cadl-emitter-framework

A prototype emitter framework for cadl (and a TypeScript emitter using it)
TypeScript
1
star