I am trying to make my code more readable and concise.
The biggest problem I am currently having is with the EventEmitter class. Every time I create a new class that uses EventEmitter I have to declare all the functions of the EventEmitter to make the class easier to understand and use.
Ex:
interface Hello {
addListener(event: 'hi', listener: (message: string) => void): this;
on(event: 'hi', listener: (message: string) => void): this;
...
}
class Hello extends EventEmitter {
constructor() { super(); }
}
I have searched around for a solution but I couldn't find anything that suits me so I tryed to come up with my own.
interface EventEmitterEvents {
[event: string]: any[];
}
interface EventEmitterType extends EventEmitter {
addListener(event: K, listener: (...args: T[K]) => void): this;
on(event: K, listener: (...args: T[K]) => void): this;
...
}
class Hello extends EventEmitter implements EventEmitterType<{'hi': [string]}> { ... }
But when I try to implement the interface EventEmitterType it throws an error
types of property 'addListener' are incompatible
I have figured out that for some reason in the 'addListener' and functions alike, type event is said to be 'string' | 'symbol' | 'number' which is incompatible with the EventEmitter where it is 'string' | 'symbol' but in the EventEmitterEvents I have defined that event is of type 'string'.
Question: Is there any way to fix this, and if not, is there any other way of recreating this functionality (not having to type all those functions)?
Edit:
If I set event argument to 'string' it will still throw error because of listener which is also incompatible with addListener saying 'any[]' is not assignable to type 'T[K]'.