From 41219d5417dfe52b46380a5413150b9414096d45 Mon Sep 17 00:00:00 2001 From: Fleny Date: Sat, 28 Dec 2024 18:38:15 +0100 Subject: [PATCH] feat(bot): Remove some clutter from desired proprerties intellisense (#4050) * Remove TBot, Use SetupDesiredProps * Remove even more clutter from intellisense * Use type instead of interfaces for some types This avoids the need for mapped types in Bot * docs: add info about removing ts clutter to desired props guide * docs: improve ts clutter section in desired props guide more --------- Co-authored-by: Awesome Stickz --- packages/bot/src/bot.ts | 11 + packages/bot/src/commandOptionsParser.ts | 2 +- packages/bot/src/desiredProperties.ts | 10 +- packages/bot/src/events.ts | 119 ++++--- packages/bot/src/helpers.ts | 231 ++++++------- packages/bot/src/transformers.ts | 420 ++++++++++++++--------- website/docs/desired-properties.md | 53 ++- 7 files changed, 501 insertions(+), 345 deletions(-) diff --git a/packages/bot/src/bot.ts b/packages/bot/src/bot.ts index b36df46d0..bd53c18e5 100644 --- a/packages/bot/src/bot.ts +++ b/packages/bot/src/bot.ts @@ -22,6 +22,17 @@ import { type Transformers, createTransformers } from './transformers.js' * @param options Configurations options used to manage this bot. * @returns Bot */ + +// Overloads to avoid adding CompleteDesiredProperties if we are given a complete object +export function createBot< + TProps extends TransformersDesiredProperties, + TBehavior extends DesiredPropertiesBehavior = DesiredPropertiesBehavior.RemoveKey, +>(options: CreateBotOptions): Bot +export function createBot< + TProps extends RecursivePartial, + TBehavior extends DesiredPropertiesBehavior = DesiredPropertiesBehavior.RemoveKey, +>(options: CreateBotOptions): Bot, TBehavior> + export function createBot< TProps extends RecursivePartial, TBehavior extends DesiredPropertiesBehavior = DesiredPropertiesBehavior.RemoveKey, diff --git a/packages/bot/src/commandOptionsParser.ts b/packages/bot/src/commandOptionsParser.ts index 6d2acd202..eb0bafda5 100644 --- a/packages/bot/src/commandOptionsParser.ts +++ b/packages/bot/src/commandOptionsParser.ts @@ -18,7 +18,7 @@ export function commandOptionsParser< TProps extends TransformersDesiredProperties & { interaction: { data: true } }, TBehavior extends DesiredPropertiesBehavior, >(__interaction: SetupDesiredProps, options?: InteractionDataOption[]): ParsedInteractionOption { - // 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 + // 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 & const interaction = __interaction as SetupDesiredProps< Interaction, CompleteDesiredProperties<{ interaction: { data: true } }>, diff --git a/packages/bot/src/desiredProperties.ts b/packages/bot/src/desiredProperties.ts index 31581f14d..4a61b0b51 100644 --- a/packages/bot/src/desiredProperties.ts +++ b/packages/bot/src/desiredProperties.ts @@ -201,10 +201,10 @@ interface TransformersDesiredPropertiesMetadata extends DesiredPropertiesMetadat } } -export function createDesiredPropertiesObject( - desiredProperties: RecursivePartial, - defaultValue = false, -): TransformersDesiredProperties { +export function createDesiredPropertiesObject, TDefault extends boolean = false>( + desiredProperties: T, + defaultValue: TDefault = false as TDefault, +): CompleteDesiredProperties { return { activityInstance: { applicationId: defaultValue, @@ -719,7 +719,7 @@ export function createDesiredPropertiesObject( volume: defaultValue, ...desiredProperties.soundboardSound, }, - } + } satisfies TransformersDesiredProperties as CompleteDesiredProperties } type KeyByValue = { diff --git a/packages/bot/src/events.ts b/packages/bot/src/events.ts index fe5f31fab..9be74ba67 100644 --- a/packages/bot/src/events.ts +++ b/packages/bot/src/events.ts @@ -1,22 +1,32 @@ import type { DiscordGatewayPayload, DiscordReady, DiscordVoiceChannelEffectAnimationType } from '@discordeno/types' import type { Collection } from '@discordeno/utils' -import type { DesiredPropertiesBehavior, TransformersDesiredProperties } from './desiredProperties.js' -import type { Bot } from './index.js' +import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from './desiredProperties.js' import type { AuditLogEntry, AutoModerationActionExecution, AutoModerationRule, + Channel, + Emoji, + Entitlement, + Guild, GuildApplicationCommandPermissions, Integration, + Interaction, + Invite, + Member, + Message, PresenceUpdate, + Role, + ScheduledEvent, + SoundboardSound, + Sticker, + Subscription, ThreadMember, + User, + VoiceState, } from './transformers/types.js' -export interface EventHandlers< - TProps extends TransformersDesiredProperties, - TBehavior extends DesiredPropertiesBehavior, - TBot extends Bot = Bot, -> { +export type EventHandlers = { debug: (text: string, ...args: any[]) => unknown applicationCommandPermissionsUpdate: (command: GuildApplicationCommandPermissions) => unknown guildAuditLogEntryCreate: (log: AuditLogEntry, guildId: bigint) => unknown @@ -24,27 +34,27 @@ export interface EventHandlers< automodRuleUpdate: (rule: AutoModerationRule) => unknown automodRuleDelete: (rule: AutoModerationRule) => unknown automodActionExecution: (payload: AutoModerationActionExecution) => unknown - threadCreate: (thread: TBot['transformers']['$inferredTypes']['channel']) => unknown - threadDelete: (thread: TBot['transformers']['$inferredTypes']['channel']) => unknown + threadCreate: (thread: SetupDesiredProps) => unknown + threadDelete: (thread: SetupDesiredProps) => unknown threadListSync: (payload: { guildId: bigint channelIds?: bigint[] - threads: TBot['transformers']['$inferredTypes']['channel'][] + threads: SetupDesiredProps[] members: ThreadMember[] }) => unknown threadMemberUpdate: (payload: { id: bigint; guildId: bigint; joinedAt: number; flags: number }) => unknown threadMembersUpdate: (payload: { id: bigint; guildId: bigint; addedMembers?: ThreadMember[]; removedMemberIds?: bigint[] }) => unknown - threadUpdate: (thread: TBot['transformers']['$inferredTypes']['channel']) => unknown - scheduledEventCreate: (event: TBot['transformers']['$inferredTypes']['scheduledEvent']) => unknown - scheduledEventUpdate: (event: TBot['transformers']['$inferredTypes']['scheduledEvent']) => unknown - scheduledEventDelete: (event: TBot['transformers']['$inferredTypes']['scheduledEvent']) => unknown + threadUpdate: (thread: SetupDesiredProps) => unknown + scheduledEventCreate: (event: SetupDesiredProps) => unknown + scheduledEventUpdate: (event: SetupDesiredProps) => unknown + scheduledEventDelete: (event: SetupDesiredProps) => unknown scheduledEventUserAdd: (payload: { guildScheduledEventId: bigint; guildId: bigint; userId: bigint }) => unknown scheduledEventUserRemove: (payload: { guildScheduledEventId: bigint; guildId: bigint; userId: bigint }) => unknown ready: ( payload: { shardId: number v: number - user: TBot['transformers']['$inferredTypes']['user'] + user: SetupDesiredProps guilds: bigint[] sessionId: string shard?: number[] @@ -52,31 +62,28 @@ export interface EventHandlers< }, rawPayload: DiscordReady, ) => unknown - interactionCreate: (interaction: TBot['transformers']['$inferredTypes']['interaction']) => unknown + interactionCreate: (interaction: SetupDesiredProps) => unknown integrationCreate: (integration: Integration) => unknown integrationDelete: (payload: { id: bigint; guildId: bigint; applicationId?: bigint }) => unknown integrationUpdate: (payload: { guildId: bigint }) => unknown - inviteCreate: (invite: TBot['transformers']['$inferredTypes']['invite']) => unknown + inviteCreate: (invite: SetupDesiredProps) => unknown inviteDelete: (payload: { channelId: bigint; guildId?: bigint; code: string }) => unknown - guildMemberAdd: (member: TBot['transformers']['$inferredTypes']['member'], user: TBot['transformers']['$inferredTypes']['user']) => unknown - guildMemberRemove: (user: TBot['transformers']['$inferredTypes']['user'], guildId: bigint) => unknown - guildMemberUpdate: (member: TBot['transformers']['$inferredTypes']['member'], user: TBot['transformers']['$inferredTypes']['user']) => unknown - guildStickersUpdate: (payload: { guildId: bigint; stickers: TBot['transformers']['$inferredTypes']['sticker'][] }) => unknown - messageCreate: (message: TBot['transformers']['$inferredTypes']['message']) => unknown - messageDelete: ( - payload: { id: bigint; channelId: bigint; guildId?: bigint }, - message?: TBot['transformers']['$inferredTypes']['message'], - ) => unknown + guildMemberAdd: (member: SetupDesiredProps, user: SetupDesiredProps) => unknown + guildMemberRemove: (user: SetupDesiredProps, guildId: bigint) => unknown + guildMemberUpdate: (member: SetupDesiredProps, user: SetupDesiredProps) => unknown + guildStickersUpdate: (payload: { guildId: bigint; stickers: SetupDesiredProps[] }) => unknown + messageCreate: (message: SetupDesiredProps) => unknown + messageDelete: (payload: { id: bigint; channelId: bigint; guildId?: bigint }, message?: SetupDesiredProps) => unknown messageDeleteBulk: (payload: { ids: bigint[]; channelId: bigint; guildId?: bigint }) => unknown - messageUpdate: (message: TBot['transformers']['$inferredTypes']['message']) => unknown + messageUpdate: (message: SetupDesiredProps) => unknown reactionAdd: (payload: { userId: bigint channelId: bigint messageId: bigint guildId?: bigint - member?: TBot['transformers']['$inferredTypes']['member'] - user?: TBot['transformers']['$inferredTypes']['user'] - emoji: TBot['transformers']['$inferredTypes']['emoji'] + member?: SetupDesiredProps + user?: SetupDesiredProps + emoji: SetupDesiredProps messageAuthorId?: bigint burst: boolean burstColors?: string[] @@ -86,14 +93,14 @@ export interface EventHandlers< channelId: bigint messageId: bigint guildId?: bigint - emoji: TBot['transformers']['$inferredTypes']['emoji'] + emoji: SetupDesiredProps burst: boolean }) => unknown reactionRemoveEmoji: (payload: { channelId: bigint messageId: bigint guildId?: bigint - emoji: TBot['transformers']['$inferredTypes']['emoji'] + emoji: SetupDesiredProps }) => unknown reactionRemoveAll: (payload: { channelId: bigint; messageId: bigint; guildId?: bigint }) => unknown presenceUpdate: (presence: PresenceUpdate) => unknown @@ -101,56 +108,56 @@ export interface EventHandlers< channelId: bigint guildId: bigint userId: bigint - emoji?: TBot['transformers']['$inferredTypes']['emoji'] + emoji?: SetupDesiredProps animationType?: DiscordVoiceChannelEffectAnimationType animationId?: number soundId?: bigint | number soundVolume?: number }) => unknown voiceServerUpdate: (payload: { token: string; endpoint?: string; guildId: bigint }) => unknown - voiceStateUpdate: (voiceState: TBot['transformers']['$inferredTypes']['voiceState']) => unknown - channelCreate: (channel: TBot['transformers']['$inferredTypes']['channel']) => unknown + voiceStateUpdate: (voiceState: SetupDesiredProps) => unknown + channelCreate: (channel: SetupDesiredProps) => unknown dispatchRequirements: (data: DiscordGatewayPayload, shardId: number) => unknown - channelDelete: (channel: TBot['transformers']['$inferredTypes']['channel']) => unknown + channelDelete: (channel: SetupDesiredProps) => unknown channelPinsUpdate: (data: { guildId?: bigint; channelId: bigint; lastPinTimestamp?: number }) => unknown - channelUpdate: (channel: TBot['transformers']['$inferredTypes']['channel']) => unknown + channelUpdate: (channel: SetupDesiredProps) => unknown stageInstanceCreate: (data: { id: bigint; guildId: bigint; channelId: bigint; topic: string }) => unknown stageInstanceDelete: (data: { id: bigint; guildId: bigint; channelId: bigint; topic: string }) => unknown stageInstanceUpdate: (data: { id: bigint; guildId: bigint; channelId: bigint; topic: string }) => unknown guildEmojisUpdate: (payload: { guildId: bigint - emojis: Collection + emojis: Collection> }) => unknown - guildBanAdd: (user: TBot['transformers']['$inferredTypes']['user'], guildId: bigint) => unknown - guildBanRemove: (user: TBot['transformers']['$inferredTypes']['user'], guildId: bigint) => unknown - guildCreate: (guild: TBot['transformers']['$inferredTypes']['guild']) => unknown + guildBanAdd: (user: SetupDesiredProps, guildId: bigint) => unknown + guildBanRemove: (user: SetupDesiredProps, guildId: bigint) => unknown + guildCreate: (guild: SetupDesiredProps) => unknown guildDelete: (id: bigint, shardId: number) => unknown guildUnavailable: (id: bigint, shardId: number) => unknown - guildUpdate: (guild: TBot['transformers']['$inferredTypes']['guild']) => unknown + guildUpdate: (guild: SetupDesiredProps) => unknown raw: (data: DiscordGatewayPayload, shardId: number) => unknown - roleCreate: (role: TBot['transformers']['$inferredTypes']['role']) => unknown + roleCreate: (role: SetupDesiredProps) => unknown roleDelete: (payload: { guildId: bigint; roleId: bigint }) => unknown - roleUpdate: (role: TBot['transformers']['$inferredTypes']['role']) => unknown + roleUpdate: (role: SetupDesiredProps) => unknown webhooksUpdate: (payload: { channelId: bigint; guildId: bigint }) => unknown - botUpdate: (user: TBot['transformers']['$inferredTypes']['user']) => unknown + botUpdate: (user: SetupDesiredProps) => unknown typingStart: (payload: { guildId: bigint | undefined channelId: bigint userId: bigint timestamp: number - member: TBot['transformers']['$inferredTypes']['member'] | undefined + member: SetupDesiredProps | undefined }) => unknown - entitlementCreate: (entitlement: TBot['transformers']['$inferredTypes']['entitlement']) => unknown - entitlementUpdate: (entitlement: TBot['transformers']['$inferredTypes']['entitlement']) => unknown - entitlementDelete: (entitlement: TBot['transformers']['$inferredTypes']['entitlement']) => unknown - subscriptionCreate: (subscription: TBot['transformers']['$inferredTypes']['subscription']) => unknown - subscriptionUpdate: (subscription: TBot['transformers']['$inferredTypes']['subscription']) => unknown - subscriptionDelete: (subscription: TBot['transformers']['$inferredTypes']['subscription']) => unknown + entitlementCreate: (entitlement: SetupDesiredProps) => unknown + entitlementUpdate: (entitlement: SetupDesiredProps) => unknown + entitlementDelete: (entitlement: SetupDesiredProps) => unknown + subscriptionCreate: (subscription: SetupDesiredProps) => unknown + subscriptionUpdate: (subscription: SetupDesiredProps) => unknown + subscriptionDelete: (subscription: SetupDesiredProps) => unknown messagePollVoteAdd: (payload: { userId: bigint; channelId: bigint; messageId: bigint; guildId?: bigint; answerId: number }) => unknown messagePollVoteRemove: (payload: { userId: bigint; channelId: bigint; messageId: bigint; guildId?: bigint; answerId: number }) => unknown - soundboardSoundCreate: (payload: TBot['transformers']['$inferredTypes']['soundboardSound']) => unknown - soundboardSoundUpdate: (payload: TBot['transformers']['$inferredTypes']['soundboardSound']) => unknown + soundboardSoundCreate: (payload: SetupDesiredProps) => unknown + soundboardSoundUpdate: (payload: SetupDesiredProps) => unknown soundboardSoundDelete: (payload: { soundId: bigint; guildId: bigint }) => unknown - soundboardSoundsUpdate: (payload: { soundboardSounds: TBot['transformers']['$inferredTypes']['soundboardSound'][]; guildId: bigint }) => unknown - soundboardSounds: (payload: { soundboardSounds: TBot['transformers']['$inferredTypes']['soundboardSound'][]; guildId: bigint }) => unknown + soundboardSoundsUpdate: (payload: { soundboardSounds: SetupDesiredProps[]; guildId: bigint }) => unknown + soundboardSounds: (payload: { soundboardSounds: SetupDesiredProps[]; guildId: bigint }) => unknown } diff --git a/packages/bot/src/helpers.ts b/packages/bot/src/helpers.ts index 9a25c5112..3a4bec0bd 100644 --- a/packages/bot/src/helpers.ts +++ b/packages/bot/src/helpers.ts @@ -101,18 +101,37 @@ import type { } from '@discordeno/types' import { snakelize } from '@discordeno/utils' import type { Bot } from './bot.js' -import type { DesiredPropertiesBehavior, TransformersDesiredProperties } from './desiredProperties.js' +import type { DesiredPropertiesBehavior, SetupDesiredProps, TransformersDesiredProperties } from './desiredProperties.js' import type { Application, ApplicationCommand, AutoModerationRule, + Channel, + Emoji, + Entitlement, + Guild, GuildApplicationCommandPermissions, + GuildOnboarding, GuildWidget, GuildWidgetSettings, Integration, + InteractionCallbackResponse, + Invite, + Member, + Message, + Role, + ScheduledEvent, + Sku, + SoundboardSound, + StageInstance, + Sticker, StickerPack, + Subscription, Template, ThreadMember, + User, + VoiceState, + Webhook, WelcomeScreen, } from './transformers/index.js' @@ -798,44 +817,39 @@ export function createBotHelpers = Bot, -> { +export type BotHelpers = { createAutomodRule: (guildId: BigString, options: CreateAutoModerationRuleOptions, reason?: string) => Promise - createChannel: (guildId: BigString, options: CreateGuildChannel, reason?: string) => Promise - createEmoji: (guildId: BigString, options: CreateGuildEmoji, reason?: string) => Promise - createApplicationEmoji: (options: CreateApplicationEmoji) => Promise + createChannel: (guildId: BigString, options: CreateGuildChannel, reason?: string) => Promise> + createEmoji: (guildId: BigString, options: CreateGuildEmoji, reason?: string) => Promise> + createApplicationEmoji: (options: CreateApplicationEmoji) => Promise> createForumThread: ( channelId: BigString, options: CreateForumPostWithMessage, reason?: string, - ) => Promise + ) => Promise> createGlobalApplicationCommand: (command: CreateApplicationCommand, options?: CreateGlobalApplicationCommandOptions) => Promise - createGuild: (options: CreateGuild) => Promise + createGuild: (options: CreateGuild) => Promise> createGuildApplicationCommand: ( command: CreateApplicationCommand, guildId: BigString, options?: CreateGuildApplicationCommandOptions, ) => Promise - createGuildFromTemplate: (templateCode: string, options: CreateGuildFromTemplate) => Promise + createGuildFromTemplate: (templateCode: string, options: CreateGuildFromTemplate) => Promise> createGuildSticker: ( guildId: BigString, options: CreateGuildStickerOptions, reason?: string, - ) => Promise + ) => Promise> createGuildTemplate: (guildId: BigString, options: CreateTemplate) => Promise