mirror of
https://github.com/discordeno/discordeno.git
synced 2026-05-30 23:40:07 +00:00
fix(bot)!: fix type errors when using commandOptionsParser (#3994)
* Fix type errors when using commandOptionsParser * remove export from TransformProperty * use TransformProperty in InteractionResolvedData * Fix CI * Remove the union on GetErrorWhenUndesired
This commit is contained in:
@@ -1,52 +1,85 @@
|
||||
import { ApplicationCommandOptionTypes } from '@discordeno/types'
|
||||
import type { Attachment, Channel, Interaction, InteractionDataOption, Member, Role, User } from './index.js'
|
||||
import type {
|
||||
Attachment,
|
||||
Channel,
|
||||
DesiredPropertiesBehavior,
|
||||
Interaction,
|
||||
InteractionDataOption,
|
||||
Member,
|
||||
Role,
|
||||
SetupDesiredProps,
|
||||
TransformProperty,
|
||||
TransformersDesiredProperties,
|
||||
User,
|
||||
WithAtLeast,
|
||||
} from './index.js'
|
||||
|
||||
export function commandOptionsParser<
|
||||
TProps extends WithAtLeast<TransformersDesiredProperties, { interaction: { data: true } }>,
|
||||
TBehavior extends DesiredPropertiesBehavior,
|
||||
>(__interaction: SetupDesiredProps<Interaction, TProps, TBehavior>, options?: InteractionDataOption[]): ParsedInteractionOption<TProps, TBehavior> {
|
||||
// This is necessary as typescript gets really confused when using __interaction alone, as it will say that 'data' does not exist despite it surely exist since we have the WithAtLeast
|
||||
const interaction = __interaction as SetupDesiredProps<
|
||||
Interaction,
|
||||
WithAtLeast<TransformersDesiredProperties, { interaction: { data: true } }>,
|
||||
DesiredPropertiesBehavior.RemoveKey
|
||||
>
|
||||
|
||||
export function commandOptionsParser(interaction: Interaction, options?: InteractionDataOption[]): ParsedInteractionOption {
|
||||
if (!interaction.data) return {}
|
||||
if (!options) options = interaction.data.options ?? []
|
||||
|
||||
const args: ParsedInteractionOption = {}
|
||||
const args: ParsedInteractionOption<TProps, TBehavior> = {}
|
||||
|
||||
for (const option of options) {
|
||||
switch (option.type) {
|
||||
case ApplicationCommandOptionTypes.SubCommandGroup:
|
||||
case ApplicationCommandOptionTypes.SubCommand:
|
||||
args[option.name] = commandOptionsParser(interaction, option.options)
|
||||
args[option.name] = commandOptionsParser(interaction, option.options) as InteractionResolvedData<TProps, TBehavior>
|
||||
break
|
||||
case ApplicationCommandOptionTypes.Channel:
|
||||
args[option.name] = interaction.data.resolved?.channels?.get(BigInt(option.value!)) as InteractionResolvedChannel
|
||||
args[option.name] = interaction.data.resolved?.channels?.get(BigInt(option.value!)) as InteractionResolvedData<TProps, TBehavior>
|
||||
break
|
||||
case ApplicationCommandOptionTypes.Role:
|
||||
args[option.name] = interaction.data.resolved?.roles?.get(BigInt(option.value!)) as Role
|
||||
args[option.name] = interaction.data.resolved?.roles?.get(BigInt(option.value!)) as InteractionResolvedData<TProps, TBehavior>
|
||||
break
|
||||
case ApplicationCommandOptionTypes.User:
|
||||
args[option.name] = {
|
||||
user: interaction.data.resolved?.users?.get(BigInt(option.value!)) as User,
|
||||
member: interaction.data.resolved?.members?.get(BigInt(option.value!)) as InteractionResolvedMember,
|
||||
user: interaction.data.resolved?.users?.get(BigInt(option.value!)) as InteractionResolvedData<TProps, TBehavior>,
|
||||
member: interaction.data.resolved?.members?.get(BigInt(option.value!)) as InteractionResolvedData<TProps, TBehavior>,
|
||||
}
|
||||
break
|
||||
case ApplicationCommandOptionTypes.Attachment:
|
||||
args[option.name] = interaction.data.resolved?.attachments?.get(BigInt(option.value!)) as Attachment
|
||||
args[option.name] = interaction.data.resolved?.attachments?.get(BigInt(option.value!)) as InteractionResolvedData<TProps, TBehavior>
|
||||
break
|
||||
case ApplicationCommandOptionTypes.Mentionable:
|
||||
// Mentionable are roles or users
|
||||
args[option.name] = (interaction.data.resolved?.roles?.get(BigInt(option.value!)) as Role) ?? {
|
||||
user: interaction.data.resolved?.users?.get(BigInt(option.value!)) as User,
|
||||
member: interaction.data.resolved?.members?.get(BigInt(option.value!)) as InteractionResolvedMember,
|
||||
args[option.name] = (interaction.data.resolved?.roles?.get(BigInt(option.value!)) as ParsedInteractionOption<TProps, TBehavior>[string]) ?? {
|
||||
user: interaction.data.resolved?.users?.get(BigInt(option.value!)) as InteractionResolvedData<TProps, TBehavior>,
|
||||
member: interaction.data.resolved?.members?.get(BigInt(option.value!)) as InteractionResolvedData<TProps, TBehavior>,
|
||||
}
|
||||
break
|
||||
default:
|
||||
args[option.name] = option.value as ParsedInteractionOption[string]
|
||||
args[option.name] = option.value as InteractionResolvedData<TProps, TBehavior>
|
||||
}
|
||||
}
|
||||
|
||||
return args
|
||||
}
|
||||
|
||||
export interface ParsedInteractionOption {
|
||||
[key: string]: string | number | boolean | InteractionResolvedUser | InteractionResolvedChannel | Role | Attachment | ParsedInteractionOption
|
||||
export interface ParsedInteractionOption<TProps extends TransformersDesiredProperties, TBehavior extends DesiredPropertiesBehavior> {
|
||||
[key: string]: InteractionResolvedData<TProps, TBehavior>
|
||||
}
|
||||
|
||||
export type InteractionResolvedData<TProps extends TransformersDesiredProperties, TBehavior extends DesiredPropertiesBehavior> =
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| TransformProperty<InteractionResolvedUser, TProps, TBehavior>
|
||||
| TransformProperty<InteractionResolvedChannel, TProps, TBehavior>
|
||||
| TransformProperty<Role, TProps, TBehavior>
|
||||
| TransformProperty<Attachment, TProps, TBehavior>
|
||||
| ParsedInteractionOption<TProps, TBehavior>
|
||||
|
||||
export interface InteractionResolvedUser {
|
||||
user: User
|
||||
member: InteractionResolvedMember
|
||||
|
||||
@@ -729,6 +729,10 @@ type Complete<TObj, TDefault> = {
|
||||
[K in keyof TObj]-?: undefined extends TObj[K] ? TDefault : Exclude<TObj[K], undefined>
|
||||
}
|
||||
|
||||
export type WithAtLeast<T extends TransformersDesiredProperties, AtLeast extends RecursivePartial<TransformersDesiredProperties>> = T & {
|
||||
[K in keyof T]: K extends keyof AtLeast ? Complete<AtLeast[K], false> & T[K] : T[K]
|
||||
}
|
||||
|
||||
type JoinTuple<T extends string[], TDelimiter extends string> = T extends readonly [infer F extends string, ...infer R extends string[]]
|
||||
? R['length'] extends 0
|
||||
? F
|
||||
@@ -811,30 +815,36 @@ type GetErrorWhenUndesired<
|
||||
TransformersDesiredPropertiesMetadata[KeyByValue<TransformersObjects, T>]['dependencies'],
|
||||
TProps[KeyByValue<TransformersObjects, T>]
|
||||
>,
|
||||
> = TIsDesired extends true ? TransformNestedProps<T[Key], TProps, TBehavior> : TIsDesired
|
||||
> = TIsDesired extends true ? TransformProperty<T[Key], TProps, TBehavior> : TIsDesired
|
||||
|
||||
type IsObject<T> = T extends object ? (T extends Function ? false : true) : false
|
||||
|
||||
// If the object is a transformed object, a collection of transformed object or an array of transformed objects we need to apply the desired props to them as well
|
||||
type TransformNestedProps<
|
||||
export type TransformProperty<
|
||||
T,
|
||||
TProps extends TransformersDesiredProperties,
|
||||
TBehavior extends DesiredPropertiesBehavior,
|
||||
> = T extends TransformersObjects[keyof TransformersObjects] // is T a transformed object?
|
||||
? // Yes, apply the desired props
|
||||
SetupDesiredProps<T, TProps, TBehavior>
|
||||
: // No, is it a collection of transformed objects?
|
||||
T extends Collection<infer U, infer UObj extends TransformersObjects[keyof TransformersObjects]>
|
||||
? // Yes, apply the desired props
|
||||
Collection<U, SetupDesiredProps<UObj, TProps, TBehavior>>
|
||||
: // No, is it an array of transformed objects?
|
||||
T extends Array<infer U extends TransformersObjects[keyof TransformersObjects]>
|
||||
: // No, is it a collection?
|
||||
T extends Collection<infer U, infer UObj>
|
||||
? // Yes, check for nested proprieties
|
||||
Collection<U, TransformProperty<UObj, TProps, TBehavior>>
|
||||
: // No, is it an array?
|
||||
T extends Array<infer U>
|
||||
? // Yes, apply the desired props
|
||||
SetupDesiredProps<U, TProps, TBehavior>[]
|
||||
TransformProperty<U, TProps, TBehavior>[]
|
||||
: // No, is it a Bot?
|
||||
T extends Bot
|
||||
? // Yes, return a bot with the correct set of props & behavior
|
||||
Bot<TProps, TBehavior>
|
||||
: // No, this is a normal value such as string / bigint / number
|
||||
T
|
||||
: // No, is this a generic object? If so we need to ensure nested inside there aren't transformed objects
|
||||
IsObject<T> extends true
|
||||
? // Yes, check of nested proprieties
|
||||
{ [K in keyof T]: TransformProperty<T[K], TProps, TBehavior> }
|
||||
: // No, this is a normal value such as string / bigint / number
|
||||
T
|
||||
|
||||
export type SetupDesiredProps<
|
||||
T extends TransformersObjects[keyof TransformersObjects],
|
||||
@@ -847,7 +857,7 @@ export type SetupDesiredProps<
|
||||
: Key]: // When the behavior is to change the type we use the GetErrorWhenUndesired type helper else apply the desired props to the key and return
|
||||
TBehavior extends DesiredPropertiesBehavior.ChangeType
|
||||
? GetErrorWhenUndesired<Key, T, TProps, TBehavior>
|
||||
: TransformNestedProps<T[Key], TProps, TBehavior>
|
||||
: TransformProperty<T[Key], TProps, TBehavior>
|
||||
}
|
||||
|
||||
export type TransformersDesiredProperties = {
|
||||
|
||||
Reference in New Issue
Block a user