I'm trying to create some kind of factory to create class for a type of some events emitted by discord.js
.
In this example, ClientEvents
are defined by discord.js
, EventInterface
define the format of the object/class used in the factory and MessageCreateEvent
is a exemple of the implementation.
I want to force the name
value of the implemented class to be a key of ClientEvent
(like in the code below but it's not working) and I want to type the args of execute
to be the associated type of the given key in ClientEvent
. For example, if the name
is messageCreate
, and DontKnowType
should be a Message
.
type Message = unknown;
type DontKnowType = unknown;
interface ClientEvents {
messageCreate: [message: Message];
}
interface EventInterface<T extends keyof { [x: string]: ClientEvents}> {
name: T,
execute: (interactObject: DontKnowType) => Promise<void | undefined>;
}
class MessageCreateEvent implements EventInterface<'messageCreate'> {
public name = 'messageCreate';
public async execute(interactObject: DontKnowType): Promise<void | undefined> {
console.info(`Message from ${interactObject?.user.tag}`);
}
}
Can you help me please ?
CodePudding user response:
It will be match clearer If you provide examples or comments on how your example should work, and how shouldn't.
But I altered your code to make validation of Message**Event classes by EventInterface
and force name to be part of Message**Event interface.
interface EventInterface<T extends keyof ClientEvents> {
name: T
execute: (...args: ClientEvents[T]) => Promise<void>;
}
class MessageCreateEvent implements EventInterface<'messageCreate'>{
public name = 'messageCreate' as const;
public async execute(message: Message): Promise<void> {
console.info(`Message from ${message!.user!.tag!}`);
}
}
Is this what you are looking for?