Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

strict-event-emitter-types

Package Overview
Dependencies
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

strict-event-emitter-types - npm Package Compare versions

Comparing version 1.2.0 to 2.0.0

types/test/examples.d.ts

2

package.json
{
"name": "strict-event-emitter-types",
"version": "1.2.0",
"version": "2.0.0",
"description": "Strictly and safely type any EventEmitter-like interface on any object",

@@ -5,0 +5,0 @@ "main": "dist/src/index.js",

## Typed Event Emitter
**NOTE: REQUIRES TYPESCRIPT 2.8 SUPPORT FOR CONDITIONAL TYPES**
**NOTE: REQUIRES TYPESCRIPT 3.0**
A TypeScript library for strongly typed event emitters in 0 kB. Works with any kind of EventEmitter.
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.
### Installing
### Installation

@@ -13,3 +13,3 @@ ```

### Usage
### Example

@@ -19,29 +19,59 @@ ```ts

// grab your event emitter
import { EventEmitter } from 'events';
// define your events
interface Events {
newValue: number,
done: void // an event with no payload
request: (request: Request, response: Response) => void;
done: void;
}
// Create a typed event emitter
// 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('newValue', x => x); // x is contextually typed to number
// now enjoy your strongly typed EventEmitter API!🎉
ee.on('somethingElse'); // Error: unknown event
ee.on('done', x => x); // Error: 'done' does not have a payload
ee.emit('newValue', 'hello!'); // Error: incorrect payload
ee.emit('newValue'); // Error: forgotten payload
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
```
### StrictEventEmitter&lt;TEmitterType, TEventRecord, TEmitRecord>
### 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:
```ts
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.
1. **`void`:** A shortcut for an event with no payload, i.e. `() => void`
1. **Anything else:** A shortcut for an event with one payload, for example `(p: number) => void` can be written as just `number`.
#### StrictEventEmitter&lt;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.
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.

@@ -69,5 +99,20 @@ 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:

##### Usage with Subclasses
To subclass an EventEmitter you need to cast the base EventEmitter to the strict EventEmitter before extending:
```ts
type MyEmitter = StrictEventEmitter<EventEmitter, Events>;
class MyEventEmitter extends (EventEmitter as { new(): MyEmitter }) {
doEmit() {
this.emit(...); // strict
}
}
```
### StrictBroadcast&lt;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.
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:

@@ -78,7 +123,10 @@

const broadcast: StrictBroadcast<ServerSocket> = function (event: string, payload?: any) {
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.

@@ -0,1 +1,2 @@

declare const assignmentCompatibilityHack: unique symbol;
export declare type MatchingKeys<TRecord, TMatch, K extends keyof TRecord = keyof TRecord> = K extends (TRecord[K] extends TMatch ? K : never) ? K : never;

@@ -8,17 +9,25 @@ export declare type VoidKeys<Record> = MatchingKeys<Record, void>;

}
export declare type OverriddenMethods<TEventRecord, TEmitRecord = TEventRecord, EventVK extends VoidKeys<TEventRecord> = VoidKeys<TEventRecord>, EventNVK extends Exclude<keyof TEventRecord, EventVK> = Exclude<keyof TEventRecord, EventVK>, EmitVK extends VoidKeys<TEmitRecord> = VoidKeys<TEmitRecord>, EmitNVK extends Exclude<keyof TEmitRecord, EmitVK> = Exclude<keyof TEmitRecord, EmitVK>> = {
on<P extends EventNVK>(event: P, listener: (m: TEventRecord[P], ...args: any[]) => void): any;
on<P extends EventVK>(event: P, listener: () => void): any;
addListener<P extends EventNVK>(event: P, listener: (m: TEventRecord[P], ...args: any[]) => void): any;
addListener<P extends EventVK>(event: P, listener: () => void): any;
addEventListener<P extends EventNVK>(event: P, listener: (m: TEventRecord[P], ...args: any[]) => void): any;
addEventListener<P extends EventVK>(event: P, listener: () => void): any;
removeListener<P extends EventVK | EventNVK>(event: P, listener: Function): any;
once<P extends EventNVK>(event: P, listener: (m: TEventRecord[P], ...args: any[]) => void): any;
once<P extends EventVK>(event: P, listener: () => void): any;
emit<P extends EmitNVK>(event: P, request: TEmitRecord[P]): any;
emit<P extends EmitVK>(event: P): any;
export declare type ReturnTypeOfMethod<T> = T extends (...args: any[]) => any ? ReturnType<T> : void;
export declare type ReturnTypeOfMethodIfExists<T, S extends string> = S extends keyof T ? ReturnTypeOfMethod<T[S]> : void;
export declare type InnerEEMethodReturnType<T, TValue, FValue> = T extends (...args: any[]) => any ? ReturnType<T> extends void | undefined ? FValue : TValue : FValue;
export declare type EEMethodReturnType<T, S extends string, TValue, FValue = void> = S extends keyof T ? InnerEEMethodReturnType<T[S], TValue, FValue> : FValue;
declare type ListenerType<T> = [T] extends [(...args: infer U) => any] ? U : [T] extends [void] ? [] : [T];
export declare type OverriddenMethods<TEmitter, TEventRecord, TEmitRecord = TEventRecord> = {
on<P extends keyof TEventRecord, T>(this: T, event: P, listener: (...args: ListenerType<TEventRecord[P]>) => void): EEMethodReturnType<TEmitter, 'on', T>;
on(event: typeof assignmentCompatibilityHack, listener: (...args: any[]) => any): void;
addListener<P extends keyof TEventRecord, T>(this: T, event: P, listener: (...args: ListenerType<TEventRecord[P]>) => void): EEMethodReturnType<TEmitter, 'addListener', T>;
addListener(event: typeof assignmentCompatibilityHack, listener: (...args: any[]) => any): void;
addEventListener<P extends keyof TEventRecord, T>(this: T, event: P, listener: (...args: ListenerType<TEventRecord[P]>) => void): EEMethodReturnType<TEmitter, 'addEventListener', T>;
addEventListener(event: typeof assignmentCompatibilityHack, listener: (...args: any[]) => any): void;
removeListener<P extends keyof TEventRecord, T>(this: T, event: P, listener: (...args: any[]) => any): EEMethodReturnType<TEmitter, 'removeListener', T>;
removeListener(event: typeof assignmentCompatibilityHack, listener: (...args: any[]) => any): void;
removeEventListener<P extends keyof TEventRecord, T>(this: T, event: P, listener: (...args: any[]) => any): EEMethodReturnType<TEmitter, 'removeEventListener', T>;
removeEventListener(event: typeof assignmentCompatibilityHack, listener: (...args: any[]) => any): void;
once<P extends keyof TEventRecord, T>(this: T, event: P, listener: (...args: ListenerType<TEventRecord[P]>) => void): EEMethodReturnType<TEmitter, 'once', T>;
once(event: typeof assignmentCompatibilityHack, listener: (...args: any[]) => any): void;
emit<P extends keyof TEmitRecord, T>(this: T, event: P, ...args: ListenerType<TEmitRecord[P]>): EEMethodReturnType<TEmitter, 'emit', T>;
emit(event: typeof assignmentCompatibilityHack, ...args: any[]): void;
};
export declare type OverriddenKeys = keyof OverriddenMethods<any, any, any>;
export declare type StrictEventEmitter<TEmitterType, TEventRecord, TEmitRecord = TEventRecord, UnneededMethods extends Exclude<OverriddenKeys, keyof TEmitterType> = Exclude<OverriddenKeys, keyof TEmitterType>, NeededMethods extends Exclude<OverriddenKeys, UnneededMethods> = Exclude<OverriddenKeys, UnneededMethods>> = TypeRecord<TEmitterType, TEventRecord, TEmitRecord> & Pick<TEmitterType, Exclude<keyof TEmitterType, OverriddenKeys>> & Pick<OverriddenMethods<TEventRecord, TEmitRecord>, NeededMethods>;
export declare type StrictEventEmitter<TEmitterType, TEventRecord, TEmitRecord = TEventRecord, UnneededMethods extends Exclude<OverriddenKeys, keyof TEmitterType> = Exclude<OverriddenKeys, keyof TEmitterType>, NeededMethods extends Exclude<OverriddenKeys, UnneededMethods> = Exclude<OverriddenKeys, UnneededMethods>> = TypeRecord<TEmitterType, TEventRecord, TEmitRecord> & Pick<TEmitterType, Exclude<keyof TEmitterType, OverriddenKeys>> & Pick<OverriddenMethods<TEmitterType, TEventRecord, TEmitRecord>, NeededMethods>;
export default StrictEventEmitter;

@@ -25,0 +34,0 @@ export declare type NoUndefined<T> = T extends undefined ? never : T;

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc