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