make description optional in options for custom IDs
vi did:web:vt3e.cat
Fri, 12 Jun 2026 20:55:11 +0100
3 files changed,
42 insertions(+),
21 deletions(-)
M
pkgs/core/src/commands.ts
→
pkgs/core/src/commands.ts
@@ -4,7 +4,7 @@ CommandInteraction,
UserContextMenuCommandInteraction, MessageContextMenuCommandInteraction, } from "discord.js"; -import type { Option, InferOptions } from "./options"; +import type { CommandOption, InferOptions } from "./options"; export const INTEGRATION_TYPES = { GUILD_INSTALL: 0,@@ -36,7 +36,7 @@ constructor(
public name: string, public config: { description: string; - options?: Record<string, Option<any, any>>; + options?: Record<string, CommandOption<any, any>>; run: Function; }, ) {}@@ -50,7 +50,7 @@ public name: string,
public description: string, ) {} - subcommand<O extends Record<string, Option<any, any>>>( + subcommand<O extends Record<string, CommandOption<any, any>>>( name: string, config: { description: string;@@ -81,7 +81,7 @@ contexts?: InteractionContextType[];
}, ) {} - subcommand<O extends Record<string, Option<any, any>>>( + subcommand<O extends Record<string, CommandOption<any, any>>>( name: string, config: { description: string;@@ -114,7 +114,7 @@ constructor(
public name: string, public config: { description: string; - options?: Record<string, Option<any, any>>; + options?: Record<string, CommandOption<any, any>>; integrationTypes?: IntegrationType[]; contexts?: InteractionContextType[]; run: Function;@@ -145,7 +145,7 @@ ): CommandBuilder<Ctx & NewCtx> {
return new CommandBuilder<Ctx & NewCtx>([...this.middlewares, mw]); } - command<O extends Record<string, Option<any, any>>>( + command<O extends Record<string, CommandOption<any, any>>>( name: string, config: { description: string;@@ -204,7 +204,7 @@ runOrConfig:
| ((interaction: MessageContextMenuCommandInteraction, ctx: Ctx) => Promise<void> | void) | { integrationTypes?: IntegrationType[]; - contexts?: InteractionContextType[]; + contexts?: IntegrationType[]; run: ( interaction: MessageContextMenuCommandInteraction, ctx: Ctx,
M
pkgs/core/src/kitten.ts
→
pkgs/core/src/kitten.ts
@@ -16,7 +16,7 @@ ApplicationCommandType,
} from "discord.js"; import { HaltExecution } from "./errors"; -import { type Option, type InferOptions, OPTION_TYPES } from "./options"; +import { type Option, type CommandOption, type InferOptions, OPTION_TYPES } from "./options"; import { KittenComponent, type KittenComponentInteraction } from "./components"; import { Command,@@ -51,7 +51,7 @@ builder() {
return new CommandBuilder(); } - command<O extends Record<string, Option<any, any>>>( + command<O extends Record<string, CommandOption<any, any>>>( name: string, config: { description: string;@@ -445,7 +445,7 @@ }
} private transformOptionsForDiscord( - options?: Record<string, Option<any, any>>, + options?: Record<string, CommandOption<any, any>>, ): APIApplicationCommandBasicOption[] { if (!options) return [];
M
pkgs/core/src/options.ts
→
pkgs/core/src/options.ts
@@ -24,13 +24,17 @@ type OptionType = keyof typeof OPTION_TYPES;
export interface Option<T, Req extends boolean> { type: OptionType; - description: string; + description?: string; required: Req; autocomplete?: ( interaction: AutocompleteInteraction, value: T, ) => Promise<ApplicationCommandOptionChoiceData[]> | ApplicationCommandOptionChoiceData[]; __type?: T; +} + +export interface CommandOption<T, Req extends boolean> extends Option<T, Req> { + description: string; } export type InferOptions<O> = {@@ -47,20 +51,37 @@ value: T,
) => Promise<ApplicationCommandOptionChoiceData[]> | ApplicationCommandOptionChoiceData[]; const createOption = <T>(type: OptionType) => { - return ((description: string, config?: any): Option<T, any> => ({ - type, - description, - required: config?.required ?? false, - autocomplete: config?.autocomplete, - })) as { - ( + return (( + descriptionOrConfig?: string | { required?: boolean; autocomplete?: AutocompleteFn<T> }, + config?: { required?: boolean; autocomplete?: AutocompleteFn<T> }, + ): Option<T, any> => { + const hasDescription = typeof descriptionOrConfig === "string"; + const description = hasDescription ? descriptionOrConfig : undefined; + const actualConfig = hasDescription ? config : descriptionOrConfig; + + return { + type, + description, + required: actualConfig?.required ?? false, + autocomplete: actualConfig?.autocomplete, + }; + }) as { + // w/ description for commands + <Req extends boolean>( description: string, - config: { required: true; autocomplete?: AutocompleteFn<T> }, - ): Option<T, true>; + config: { required: Req; autocomplete?: AutocompleteFn<T> }, + ): CommandOption<T, Req>; ( description: string, config?: { required?: false; autocomplete?: AutocompleteFn<T> }, - ): Option<T, false>; + ): CommandOption<T, false>; + + // w/out description for components + <Req extends boolean>(config: { + required: Req; + autocomplete?: AutocompleteFn<T>; + }): Option<T, Req>; + (config?: { required?: false; autocomplete?: AutocompleteFn<T> }): Option<T, false>; }; };