├── .gitignore ├── LICENSE ├── README.md ├── lib ├── index.d.ts └── index.js ├── package.json └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Zurab Benashvili (binier) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # tiny-typed-emitter 2 | 3 | Have your events and their listeners type-checked with [no overhead](#no-overhead). 4 | 5 | [![npm version](https://badge.fury.io/js/tiny-typed-emitter.svg)](https://badge.fury.io/js/tiny-typed-emitter) 6 | 7 | ## Install 8 | Simply add the dependency using **npm**: 9 | ```console 10 | $ npm i tiny-typed-emitter 11 | ``` 12 | or using **yarn**: 13 | ```console 14 | $ yarn add tiny-typed-emitter 15 | ``` 16 | 17 | ## Usage 18 | 19 | 1. import **tiny-typed-emitter** library: 20 | 21 | ```ts 22 | import { TypedEmitter } from 'tiny-typed-emitter'; 23 | ``` 24 | 25 | 2. define events and their listener signatures (**note:** quotes around event names are not mandatory): 26 | ```ts 27 | interface MyClassEvents { 28 | 'added': (el: string, wasNew: boolean) => void; 29 | 'deleted': (deletedCount: number) => void; 30 | } 31 | ``` 32 | 33 | 3. on this step depending on your use case, you can: 34 | - define your custom class extending `EventEmitter`: 35 | ```ts 36 | class MyClass extends TypedEmitter { 37 | constructor() { 38 | super(); 39 | } 40 | } 41 | ``` 42 | - create new event emitter instance: 43 | ```ts 44 | const emitter = new TypedEmitter(); 45 | ``` 46 | 47 | ## Generic events interface 48 | To use with generic events interface: 49 | 50 | ```ts 51 | interface MyClassEvents { 52 | 'added': (el: T, wasNew: boolean) => void; 53 | } 54 | 55 | class MyClass extends TypedEmitter> { 56 | 57 | } 58 | ``` 59 | 60 | ## Compatible subclasses with different events 61 | 62 | The type of `eventNames()` is a superset of the actual event names to make 63 | subclasses of a `TypedEmitter` that introduce different events type 64 | compatible. For example the following is possible: 65 | 66 | ```ts 67 | class Animal=ListenerSignature> extends TypedEmitter<{spawn: () => void} & E> { 68 | constructor() { 69 | super(); 70 | } 71 | } 72 | 73 | class Frog> extends Animal<{jump: () => void} & E> { 74 | } 75 | 76 | class Bird> extends Animal<{fly: () => void} & E> { 77 | } 78 | 79 | const animals: Animal[] = [new Frog(), new Bird()]; 80 | ``` 81 | 82 | ## No Overhead 83 | Library adds no overhead. All it does is it simply reexports renamed `EventEmitter` 84 | with customized typings. 85 | You can check **lib/index.js** to see the exported code. 86 | -------------------------------------------------------------------------------- /lib/index.d.ts: -------------------------------------------------------------------------------- 1 | export type ListenerSignature = { 2 | [E in keyof L]: (...args: any[]) => any; 3 | }; 4 | 5 | export type DefaultListener = { 6 | [k: string]: (...args: any[]) => any; 7 | }; 8 | 9 | export class TypedEmitter = DefaultListener> { 10 | static defaultMaxListeners: number; 11 | addListener(event: U, listener: L[U]): this; 12 | prependListener(event: U, listener: L[U]): this; 13 | prependOnceListener(event: U, listener: L[U]): this; 14 | removeListener(event: U, listener: L[U]): this; 15 | removeAllListeners(event?: keyof L): this; 16 | once(event: U, listener: L[U]): this; 17 | on(event: U, listener: L[U]): this; 18 | off(event: U, listener: L[U]): this; 19 | emit(event: U, ...args: Parameters): boolean; 20 | eventNames(): U[]; 21 | listenerCount(type: keyof L): number; 22 | listeners(type: U): L[U][]; 23 | rawListeners(type: U): L[U][]; 24 | getMaxListeners(): number; 25 | setMaxListeners(n: number): this; 26 | } 27 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.TypedEmitter = require("events").EventEmitter; 4 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tiny-typed-emitter", 3 | "version": "2.1.0", 4 | "description": "Fully type-checked EventEmitter", 5 | "main": "lib/index", 6 | "repository": "https://github.com/binier/tiny-typed-emitter.git", 7 | "author": "Zurab Benashvili ", 8 | "license": "MIT", 9 | "keywords": [ 10 | "tiny-typed-emitter", 11 | "typed-event-emitter", 12 | "typescript", 13 | "typescript-library", 14 | "typescript-boilerplate", 15 | "nodejs", 16 | "nodejs-library", 17 | "event", 18 | "events", 19 | "event-emitter", 20 | "event-emitters", 21 | "eventemitter", 22 | "eventemitter3", 23 | "definitelytyped", 24 | "typings", 25 | "definitely-typed" 26 | ], 27 | "files": [ 28 | "lib/*" 29 | ], 30 | "scripts": { 31 | "release": "npm publish" 32 | }, 33 | "devDependencies": { 34 | "@types/node": "^13.13.4", 35 | "typescript": "^3.8.3" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "declaration": true, 6 | "declarationMap": true, 7 | "sourceMap": true, 8 | "outDir": "./lib", 9 | "strict": true, 10 | "noImplicitAny": true, 11 | "strictNullChecks": true, 12 | "strictFunctionTypes": true, 13 | "strictBindCallApply": true, 14 | "strictPropertyInitialization": true, 15 | "noImplicitThis": true, 16 | "alwaysStrict": true, 17 | 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "noImplicitReturns": true, 21 | "noFallthroughCasesInSwitch": true, 22 | 23 | "moduleResolution": "node", 24 | "allowSyntheticDefaultImports": true, 25 | "esModuleInterop": true, 26 | 27 | "forceConsistentCasingInFileNames": true 28 | } 29 | } --------------------------------------------------------------------------------