import { type AutocompleteInteraction, type User, type Attachment, type Role, type GuildBasedChannel, type ApplicationCommandOptionChoiceData, } from "discord.js"; export const OPTION_TYPES = { subcommand: 1, subcommandGroup: 2, string: 3, integer: 4, boolean: 5, user: 6, channel: 7, role: 8, mentionable: 9, number: 10, attachment: 11, } as const; type OptionType = keyof typeof OPTION_TYPES; export interface Option { type: OptionType; description: string; required: Req; autocomplete?: ( interaction: AutocompleteInteraction, value: T, ) => Promise | ApplicationCommandOptionChoiceData[]; __type?: T; } export type InferOptions = { [K in keyof O]: O[K] extends Option ? Required extends true ? Type : Type | undefined : never; }; export type AutocompleteFn = ( interaction: AutocompleteInteraction, value: T, ) => Promise | ApplicationCommandOptionChoiceData[]; const createOption = (type: OptionType) => { return ((description: string, config?: any): Option => ({ type, description, required: config?.required ?? false, autocomplete: config?.autocomplete, })) as { ( description: string, config: { required: true; autocomplete?: AutocompleteFn }, ): Option; ( description: string, config?: { required?: false; autocomplete?: AutocompleteFn }, ): Option; }; }; export const option = { string: createOption("string"), integer: createOption("integer"), number: createOption("number"), boolean: createOption("boolean"), user: createOption("user"), channel: createOption("channel"), role: createOption("role"), mentionable: createOption("mentionable"), attachment: createOption("attachment"), };