Add TypedEmitter

This commit is contained in:
Jerko Steiner 2019-11-15 20:28:13 -03:00
parent 15ef955811
commit 45b5a3bbf2
2 changed files with 93 additions and 0 deletions

View File

@ -0,0 +1,74 @@
import { TypedEmitter } from './TypedEmitter'
import { EventEmitter } from 'events'
describe('TypedEmitter', () => {
let stringMock: jest.Mock<void, [string]>
let numberMock: jest.Mock<void, [number]>
let valueMock: jest.Mock<void, [Value]>
beforeEach(() => {
stringMock = jest.fn()
numberMock = jest.fn()
valueMock = jest.fn()
})
const listener1 = (arg: string) => {
stringMock(arg)
}
const listener2 = (arg: number) => {
numberMock(arg)
}
const listener3 = (arg: Value) => {
valueMock(arg)
}
interface Value {
a: number
}
interface Events {
test1: string
test2: number
test3: Value
}
let emitter: TypedEmitter<Events>
beforeEach(() => {
emitter = new EventEmitter()
emitter.addListener('test1', listener1)
emitter.on('test2', listener2)
emitter.once('test3', listener3)
})
describe('addListener & on', () => {
it('adds an event emitter', () => {
emitter.emit('test1', 'value')
emitter.emit('test2', 3)
expect(stringMock.mock.calls).toEqual([[ 'value' ]])
expect(numberMock.mock.calls).toEqual([[ 3 ]])
})
})
describe('once', () => {
it('adds an event emitter for one use only', () => {
emitter.emit('test3', { a: 1 })
emitter.emit('test3', { a: 2 })
expect(valueMock.mock.calls).toEqual([[ { a: 1 } ]])
})
})
describe('removeListener & off', () => {
it('removes an event listener', () => {
emitter.removeListener('test1', listener1)
emitter.off('test2', listener2)
emitter.emit('test1', 'value')
emitter.emit('test2', 3)
expect(stringMock.mock.calls).toEqual([])
expect(numberMock.mock.calls).toEqual([])
})
})
})

View File

@ -0,0 +1,19 @@
import { EventEmitter } from 'events'
type Callback<A> = (a: A) => void
// eslint-disable-next-line
type Events = Record<string | symbol, any>
export interface TypedEmitter<E extends Events>
extends EventEmitter {
addListener<K extends keyof E>(t: K, callback: Callback<E[K]>): this
removeListener<K extends keyof E>(t: K, callback: Callback<E[K]>): this
on<K extends keyof E>(t: K, callback: Callback<E[K]>): this
once<K extends keyof E>(t: K, callback: Callback<E[K]>): this
off<K extends keyof E>(t: K, callback: Callback<E[K]>): this
emit<K extends keyof E>(t: K, value: E[K]): boolean
}