Add TypedEmitter
This commit is contained in:
parent
15ef955811
commit
45b5a3bbf2
74
src/shared/TypedEmitter.test.ts
Normal file
74
src/shared/TypedEmitter.test.ts
Normal 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([])
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
19
src/shared/TypedEmitter.ts
Normal file
19
src/shared/TypedEmitter.ts
Normal 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
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user