fix: required options

This commit is contained in:
MARCROCK22 2024-10-13 21:33:02 +00:00
parent b059fa14b3
commit 329ce54943
2 changed files with 80 additions and 47 deletions

View File

@ -73,25 +73,33 @@ export type CommandOption = CommandOptionWithoutName & { name: string };
export type OptionsRecord = Record<string, CommandOptionWithoutName & { type: ApplicationCommandOptionType }>; export type OptionsRecord = Record<string, CommandOptionWithoutName & { type: ApplicationCommandOptionType }>;
type KeysWithoutRequired<T extends OptionsRecord> = { type KeysWithoutRequired<T extends OptionsRecord> = {
[K in keyof T]-?: T[K]['required'] extends true ? never : K; [K in keyof T]-?: NonNullable<T[K]['required']> extends true ? never : K;
}[keyof T]; }[keyof T];
type ContextOptionsAuxInternal<
T extends CommandBaseOption & {
type: ApplicationCommandOptionType;
},
> = T['value'] extends (...args: any) => any
? Parameters<Parameters<T['value']>[1]>[0]
: NonNullable<T['value']> extends (...args: any) => any
? Parameters<Parameters<NonNullable<T['value']>>[1]>[0] extends never
? T extends SeyfertStringOption | SeyfertNumberOption
? NonNullable<T['choices']> extends SeyfertChoice<string | number>[]
? NonNullable<T['choices']>[number]['value']
: ReturnOptionsTypes[T['type']]
: ReturnOptionsTypes[T['type']]
: Parameters<Parameters<NonNullable<T['value']>>[1]>[0]
: T extends SeyfertStringOption | SeyfertNumberOption
? NonNullable<T['choices']> extends SeyfertChoice<string | number>[]
? NonNullable<T['choices']>[number]['value']
: ReturnOptionsTypes[T['type']]
: ReturnOptionsTypes[T['type']];
type ContextOptionsAux<T extends OptionsRecord> = { type ContextOptionsAux<T extends OptionsRecord> = {
[K in Exclude<keyof T, KeysWithoutRequired<T>>]: T[K]['value'] extends (...args: any) => any [K in Exclude<keyof T, KeysWithoutRequired<T>>]: ContextOptionsAuxInternal<T[K]>;
? Parameters<Parameters<T[K]['value']>[1]>[0]
: T[K] extends SeyfertStringOption | SeyfertNumberOption
? NonNullable<T[K]['choices']> extends SeyfertChoice<string | number>[]
? NonNullable<T[K]['choices']>[number]['value']
: ReturnOptionsTypes[T[K]['type']]
: ReturnOptionsTypes[T[K]['type']];
} & { } & {
[K in KeysWithoutRequired<T>]?: T[K]['value'] extends (...args: any) => any [K in KeysWithoutRequired<T>]?: ContextOptionsAuxInternal<T[K]>;
? Parameters<Parameters<T[K]['value']>[1]>[0]
: T[K] extends SeyfertStringOption | SeyfertNumberOption
? NonNullable<T[K]['choices']> extends SeyfertChoice<string | number>[]
? NonNullable<T[K]['choices']>[number]['value']
: ReturnOptionsTypes[T[K]['type']]
: ReturnOptionsTypes[T[K]['type']];
}; };
export type ContextOptions<T extends OptionsRecord> = ContextOptionsAux<T>; export type ContextOptions<T extends OptionsRecord> = ContextOptionsAux<T>;

View File

@ -18,8 +18,8 @@ import {
import type { CommandContext } from './chatcontext'; import type { CommandContext } from './chatcontext';
import type { DefaultLocale, MiddlewareContext, OKFunction, StopFunction } from './shared'; import type { DefaultLocale, MiddlewareContext, OKFunction, StopFunction } from './shared';
export interface SeyfertBasicOption<T extends keyof ReturnOptionsTypes> { export interface SeyfertBasicOption<T extends keyof ReturnOptionsTypes, R = true | false> {
required?: boolean; required?: R;
value?( value?(
data: { context: CommandContext; value: ReturnOptionsTypes[T] }, data: { context: CommandContext; value: ReturnOptionsTypes[T] },
ok: OKFunction<any>, ok: OKFunction<any>,
@ -37,10 +37,12 @@ export interface SeyfertBasicOption<T extends keyof ReturnOptionsTypes> {
export interface SeyfertBaseChoiceableOption< export interface SeyfertBaseChoiceableOption<
T extends keyof ReturnOptionsTypes, T extends keyof ReturnOptionsTypes,
C = T extends ChoiceableTypes ? SeyfertChoice<ChoiceableValues[T]>[] : never, C = T extends ChoiceableTypes ? SeyfertChoice<ChoiceableValues[T]>[] : never,
R = true | false,
VC = never,
> { > {
required?: boolean; required?: R;
choices?: C; choices?: C;
value?: ValueCallback<T, C>; value?: ValueCallback<T, C, VC>;
description: string; description: string;
description_localizations?: APIApplicationCommandBasicOption['description_localizations']; description_localizations?: APIApplicationCommandBasicOption['description_localizations'];
name_localizations?: APIApplicationCommandBasicOption['name_localizations']; name_localizations?: APIApplicationCommandBasicOption['name_localizations'];
@ -68,6 +70,7 @@ export interface ChoiceableValues {
export type ValueCallback< export type ValueCallback<
T extends keyof ReturnOptionsTypes, T extends keyof ReturnOptionsTypes,
C = T extends ChoiceableTypes ? SeyfertChoice<ChoiceableValues[T]>[] : never, C = T extends ChoiceableTypes ? SeyfertChoice<ChoiceableValues[T]>[] : never,
I = any,
> = ( > = (
data: { data: {
context: CommandContext; context: CommandContext;
@ -79,85 +82,107 @@ export type ValueCallback<
: ReturnOptionsTypes[T] : ReturnOptionsTypes[T]
: ReturnOptionsTypes[T]; : ReturnOptionsTypes[T];
}, },
ok: OKFunction<any>, ok: OKFunction<I>,
fail: StopFunction, fail: StopFunction,
) => Awaitable<void>; ) => Awaitable<void>;
export type SeyfertStringOption<T = SeyfertChoice<string>[]> = SeyfertBaseChoiceableOption< export type SeyfertStringOption<T = SeyfertChoice<string>[], R = boolean, VC = never> = SeyfertBaseChoiceableOption<
ApplicationCommandOptionType.String, ApplicationCommandOptionType.String,
T T,
R,
VC
> & { > & {
autocomplete?: AutocompleteCallback; autocomplete?: AutocompleteCallback;
onAutocompleteError?: OnAutocompleteErrorCallback; onAutocompleteError?: OnAutocompleteErrorCallback;
min_length?: number; min_length?: number;
max_length?: number; max_length?: number;
}; };
export type SeyfertIntegerOption<T = SeyfertChoice<number>[]> = SeyfertBaseChoiceableOption< export type SeyfertIntegerOption<T = SeyfertChoice<number>[], R = boolean, VC = never> = SeyfertBaseChoiceableOption<
ApplicationCommandOptionType.Integer, ApplicationCommandOptionType.Integer,
T T,
R,
VC
> & { > & {
autocomplete?: AutocompleteCallback; autocomplete?: AutocompleteCallback;
onAutocompleteError?: OnAutocompleteErrorCallback; onAutocompleteError?: OnAutocompleteErrorCallback;
min_value?: number; min_value?: number;
max_value?: number; max_value?: number;
}; };
export type SeyfertNumberOption<T = SeyfertChoice<number>[]> = SeyfertBaseChoiceableOption< export type SeyfertNumberOption<T = SeyfertChoice<number>[], R = boolean, VC = never> = SeyfertBaseChoiceableOption<
ApplicationCommandOptionType.Number, ApplicationCommandOptionType.Number,
T T,
R,
VC
> & { > & {
autocomplete?: AutocompleteCallback; autocomplete?: AutocompleteCallback;
onAutocompleteError?: OnAutocompleteErrorCallback; onAutocompleteError?: OnAutocompleteErrorCallback;
min_value?: number; min_value?: number;
max_value?: number; max_value?: number;
}; };
export type SeyfertBooleanOption = SeyfertBasicOption<ApplicationCommandOptionType.Boolean>; export type SeyfertBooleanOption<R = boolean> = SeyfertBasicOption<ApplicationCommandOptionType.Boolean, R>;
export type SeyfertUserOption = SeyfertBasicOption<ApplicationCommandOptionType.User>; export type SeyfertUserOption<R = boolean> = SeyfertBasicOption<ApplicationCommandOptionType.User, R>;
export type SeyfertChannelOption = SeyfertBasicOption<ApplicationCommandOptionType.Channel> & { export type SeyfertChannelOption<R = boolean> = SeyfertBasicOption<ApplicationCommandOptionType.Channel, R> & {
channel_types?: ChannelType[]; channel_types?: ChannelType[];
}; };
export type SeyfertRoleOption = SeyfertBasicOption<ApplicationCommandOptionType.Role>; export type SeyfertRoleOption<R = boolean> = SeyfertBasicOption<ApplicationCommandOptionType.Role, R>;
export type SeyfertMentionableOption = SeyfertBasicOption<ApplicationCommandOptionType.Mentionable>; export type SeyfertMentionableOption<R = boolean> = SeyfertBasicOption<ApplicationCommandOptionType.Mentionable, R>;
export type SeyfertAttachmentOption = SeyfertBasicOption<ApplicationCommandOptionType.Attachment>; export type SeyfertAttachmentOption<R = boolean> = SeyfertBasicOption<ApplicationCommandOptionType.Attachment, R>;
export function createStringOption<C extends SeyfertChoice<string>[] = SeyfertChoice<string>[]>( export function createStringOption<
data: SeyfertStringOption<C>, R extends boolean,
) { C extends SeyfertChoice<string>[] = SeyfertChoice<string>[],
VC = never,
>(data: SeyfertStringOption<C, R, VC>) {
return { ...data, type: ApplicationCommandOptionType.String } as const; return { ...data, type: ApplicationCommandOptionType.String } as const;
} }
export function createIntegerOption<C extends SeyfertChoice<number>[] = SeyfertChoice<number>[]>( export function createIntegerOption<
data: SeyfertIntegerOption<C>, R extends boolean,
) { C extends SeyfertChoice<number>[] = SeyfertChoice<number>[],
VC = never,
>(data: SeyfertIntegerOption<C, R, VC>) {
return { ...data, type: ApplicationCommandOptionType.Integer } as const; return { ...data, type: ApplicationCommandOptionType.Integer } as const;
} }
export function createNumberOption<C extends SeyfertChoice<number>[] = SeyfertChoice<number>[]>( export function createNumberOption<
data: SeyfertNumberOption<C>, R extends boolean,
) { C extends SeyfertChoice<number>[] = SeyfertChoice<number>[],
VC = never,
>(data: SeyfertNumberOption<C, R, VC>) {
return { ...data, type: ApplicationCommandOptionType.Number } as const; return { ...data, type: ApplicationCommandOptionType.Number } as const;
} }
export function createBooleanOption<T extends SeyfertBooleanOption = SeyfertBooleanOption>(data: T) { export function createBooleanOption<R extends boolean, T extends SeyfertBooleanOption<R> = SeyfertBooleanOption<R>>(
data: T,
) {
return { ...data, type: ApplicationCommandOptionType.Boolean } as const; return { ...data, type: ApplicationCommandOptionType.Boolean } as const;
} }
export function createUserOption<T extends SeyfertUserOption = SeyfertUserOption>(data: T) { export function createUserOption<R extends boolean, T extends SeyfertUserOption<R> = SeyfertUserOption<R>>(data: T) {
return { ...data, type: ApplicationCommandOptionType.User } as const; return { ...data, type: ApplicationCommandOptionType.User } as const;
} }
export function createChannelOption<T extends SeyfertChannelOption = SeyfertChannelOption>(data: T) { export function createChannelOption<R extends boolean, T extends SeyfertChannelOption<R> = SeyfertChannelOption<R>>(
data: T,
) {
return { ...data, type: ApplicationCommandOptionType.Channel } as const; return { ...data, type: ApplicationCommandOptionType.Channel } as const;
} }
export function createRoleOption<T extends SeyfertRoleOption = SeyfertRoleOption>(data: T) { export function createRoleOption<R extends boolean, T extends SeyfertRoleOption<R> = SeyfertRoleOption<R>>(data: T) {
return { ...data, type: ApplicationCommandOptionType.Role } as const; return { ...data, type: ApplicationCommandOptionType.Role } as const;
} }
export function createMentionableOption<T extends SeyfertMentionableOption = SeyfertMentionableOption>(data: T) { export function createMentionableOption<
R extends boolean,
T extends SeyfertMentionableOption<R> = SeyfertMentionableOption<R>,
>(data: T) {
return { ...data, type: ApplicationCommandOptionType.Mentionable } as const; return { ...data, type: ApplicationCommandOptionType.Mentionable } as const;
} }
export function createAttachmentOption<T extends SeyfertAttachmentOption = SeyfertAttachmentOption>(data: T) { export function createAttachmentOption<
R extends boolean,
T extends SeyfertAttachmentOption<R> = SeyfertAttachmentOption<R>,
>(data: T) {
return { ...data, type: ApplicationCommandOptionType.Attachment } as const; return { ...data, type: ApplicationCommandOptionType.Attachment } as const;
} }