#How do I avoid using "any" for parameters in an event handler that takes any event as an argument?

4 messages · Page 1 of 1 (latest)

next idol
  • I'm writing an event handler 'manager' such that I can group event handlers by bot features.
  • For example, I want to have ExperienceEventHandler which contains functions for the MessageCreate and MessageReactionAdd events.
export const ExperienceEventHandler = new Collection<Events, (...parameters: any) => Promise<void>>([
    [Events.MessageCreate, async (message: Message) => {
        console.log(message)
    }],
    [Events.MessageReactionAdd, async (messageReaction: MessageReaction, user: User) => {
        console.log(messageReaction, user)
    }]
])
  • Using the client.on() method, I want to call a method like EventHandlerManager.handleEvent() which will take the event and the parameters.
client.on(Events.MessageCreate, async (message) => {
    eventHandlerManager.handleEvent(Events.MessageCreate, message)
})

client.on(Events.MessageReactionAdd, async (messageReaction, user) => {
    eventHandlerManager.handleEvent(Events.MessageReactionAdd, messageReaction, user)
})

  • This will then loop through the registered event handlers and execute the relevant functions.
export class EventHandlerManager {
    private eventHandlers = [ExperienceEventHandler]

    public async handleEvent(event: Events, ...parameters: any) {
        for (const eventHandler of this.eventHandlers) {
            await eventHandler.get(event)?.(...parameters)
        }
    }
}

The good thing is that, in its current state, it works. My problem is with the types and more specifically, using any for the parameters. The difficult part is that each event requires a unique set of parameters and the parameters chosen depend on the event that is passed. I've fought with ChatGPT over the problem and tried my own ideas but couldn't figure out how to execute them correctly:

pliant gladeBOT
  • Consider reading #how-to-get-help to improve your question!
  • Explain what exactly your issue is.
  • Post the full error stack trace, not just the top part!
  • Show your code!
  • Issue solved? Press the button!
next idol
  1. Creating a Parameters type to use in the handleEvent() method which uses the collection to come up with the correct type
  • I think this was along the right lines but I couldn't work out how to do it and I kept getting errors
  1. Using a type that contains all the parameters which can be accessed using an Event as a key
  • I tried using generics but then it would give me errors about indexing using Events but I'm still fairly new to it so maybe my approach was wrong
  1. Somehow inferring the parameter types from the client.on() method
  • I couldn't figure out whether this would be possible at all
sacred nacelle

Take a look at ClientEvents. That does exactly that for client.on(). You‘d type your collection as <T extends keyof ClientEvents, (... args: ClientEvents[T]) => Awaitable<void>> (or something like that, would have to test myself for the exact usage of the generic here)