Home > OS >  Typescript - force value to be a proprerty of an interface
Typescript - force value to be a proprerty of an interface

Time:10-16

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!}`);
    }
}

full example in Playground

Is this what you are looking for?

  • Related