是的,有一个很棒的包叫做类型发射器(项目链接) https://github.com/andywer/typed-emitter这对我来说非常有效。
来自他们的文档:
import {EventEmitter} from "events" // I made a slight change here as I've needed to explicitly import EventEmitter from events
import TypedEmitter from "typed-emitter"
// Define your emitter's types like that:
// Key: Event name; Value: Listener function signature
interface MessageEvents {
error: (error: Error) => void,
message: (body: string, from: string) => void
}
const messageEmitter = new EventEmitter() as TypedEmitter<MessageEvents>
// Good ????
messageEmitter.emit("message", "Hi there!", "[email protected] /cdn-cgi/l/email-protection")
// TypeScript will catch those mistakes ✋
messageEmitter.emit("mail", "Hi there!", "[email protected] /cdn-cgi/l/email-protection")
messageEmitter.emit("message", "Hi there!", true)
// Good ????
messageEmitter.on("error", (error: Error) => { /* ... */ })
// TypeScript will catch those mistakes ✋
messageEmitter.on("error", (error: string) => { /* ... */ })
messageEmitter.on("failure", (error: Error) => { /* ... */ })
class MyEventEmitter extends (EventEmitter as new () => TypedEmitter<MyEvents>) {
// ...
}
对于您的示例,这应该有效:
import { EventEmitter } from 'events';
import TypedEmitter from "typed-emitter"
interface Payload {
id: string;
weight: number;
}
interface CustomEventEmitterEvents {
my_event: (data: Payload) => void
}
class CustomEventEmitter extends (EventEmitter as new () => TypedEmitter<CustomEventEmitterEvents>) {
constructor() {
super();
this.on('my_event', (data) => {
// I would like data to be implicitly inferred as Payload type
console.log(data.weight); // This should compile
console.log(data.something); // This should not compile
});
}
}