import EventEmitter from 'events';
type Bar = {
just: string;
test: number;
};
class Foo extends EventEmitter {
constructor() {
super();
this.addListener('my_event', (bar: Bar) => {
console.log(bar);
});
}
}
const foo = new Foo();
foo.emit('my_event', {
/* The question is: */
/* How to tip the argument key when I enter the `ctrl space` keyboard ? */
});
I don't know how to define the callback argument shape, then the vscode can tip me the event argument key when I enter the ctrl&space
keyboard.
CodePudding user response:
See this example:
import EventEmitter from 'events';
type EventMap = {
foo: string;
bar: number;
};
class CustomEvents extends EventEmitter {
constructor() {
super();
this.addListener('bar', (bar) => {
// bar is a number
console.log(bar);
});
}
addListener<Name extends keyof EventMap>(event: Name, cb: (args: EventMap[Name]) => void) {
this.addListener(event, cb)
return this
}
emit<Name extends keyof EventMap>(event: Name, payload: EventMap[Name]) {
this.emit(event, payload)
return true
}
}
const foo = new CustomEvents();
foo.addListener('bar', (arg) => {
arg.toExponential() // ok, because arg is number
})
foo.addListener('bar', (arg: string) => {
arg.toExponential() // expected error, because arg should be a number
})
foo.emit('bar', 'string') // expected error because payload sjould be a number
you need to create your own methods addListener
and emit
with appropriate validation. Also, please keep in mind that you need an event map type, where each KEY is an event name and property is an event payload.
You can check my article about typing publish/subscribe pattern