I'm trying to implement an event emitter API, and I want the child class can automatically inherit the parent event interfaces, Here is my code:
class Emitter<Events = {}> {
emit<N extends keyof Events>(name: N, ...args: Parameters<Events[N] & ((...args: any[]) => void)>) {}
}
interface AnimalEvents {
eat: (food: string) => void
}
class Animal<Events> extends Emitter<AnimalEvents & Events>{
constructor() {
super()
this.emit('eat', 'fish')
}
}
interface CatEvents {
miaow: (whom: string) => void
}
class Cat<Events> extends Animal<CatEvents & Events>{
constructor() {
super()
this.emit('eat', 'fish')
this.emit('miaow', 'me')
}
}
Two problems I got:
1. Mistake in the fish
of this.emit('eat', 'fish')
: Argument of type '[string]' is not assignable to parameter of type 'Parameters<(AnimalEvents & Events)["eat"] & ((...args: any[]) => void)>'.
.
- I can't get type limitation of arguments for defined event type, e.g., I can only got type limitation
...args[]
atthis.emit('eat', HERE)
, but notfood: string
I defined in AnimalEvents.
So, what can I do to make the interface extends work, and got arguments limitation and suggestion when I input this.emit(name, ...)
.