IanMitchell / interaction-kit

Interaction Kit is a framework for creating Discord slash command bots over the HTTP API
https://interactionkit.dev
121 stars 18 forks source link

Incorrect typing for `interaction.options` #55

Open joseywoermann opened 3 years ago

joseywoermann commented 3 years ago

Describe the bug Currently, interaction.options is typed as {}. This causes TypeScript to throw an error (Property 'question' does not exist on type '{}'). Logging interaction.options to the console, you get {}.

Instead, it should be typed as

Record<string, string | number | boolean | User | Role | Channel>

To Reproduce

import { Command, StringInput } from 'interaction-kit';

export default new Command({
  name: '8ball',
  description: 'Ask the magic Eight Ball',
  options: [
    new StringInput({
      name: 'question',
      description: 'What do you want the Magic Eight Ball to answer?',
      required: true,
    }),
  ],
  handler: (interaction) => {
    interaction.reply({
      message: `> ${interaction.options.question}\n\n🎱 | Flip a coin lolol`, // TS error here
    });
  },
});

Additional context I found the typings in node_modules\interaction-kit\dist\index.d.ts on line 459 , but I couldn't find them in the repository

Rodentman87 commented 2 years ago

So I did make some nice typings (nice for the end user, the typings in the code are mildly ugly) for my slash command library I was making. It makes interaction.options into a strongly typed object, where each option is mapped to a property and the type of each property is based on what the actual option's type is. This also includes making a string type with choices into a union of just the choices, etc.

It's really nice for the end user, but there is some drawbacks to it. The first drawback is that the options needs to be a readonly array, which doesn't seem to be much of an issue for the library, but the end user will need to make sure to use as const after the array for the typings to work right. (e.g. const options = [...] as const; which is syntax people probably aren't used to) This is a drawback of the type system, and there's no workaround for it. The second drawback is that the code does get a bit ugly since there's a few different intermediate types to transform all of the options.

The other benefit is that the handlers can be dynamic so that when autocomplete gets added, it will only prompt for an autcomplete if the command has an option with autocomplete on it. You can see the stuff in action here: https://github.com/Rodentman87/slash-command-library (there's no docs, and it's a mess, but it does work with the types)

IanMitchell commented 2 years ago

oooh I think we're doing something kind of similar; your code is a little beyond me without slowly reading it, but going to take a closer look in the morning to see what I can steal from it