discordjs / discord-api-types

Up to date Discord API Typings, versioned by the API version
https://discord-api-types.dev
MIT License
536 stars 117 forks source link

Interface to associate GatewayDispatchEvents and relevant DataPayload (proposed code below) #617

Closed john-batch closed 2 years ago

john-batch commented 2 years ago

Feature

A good addition would be an interface to associate a GatewayDispatchEvents event with the relevant DataPayload dispatched along this event.

Ideal solution or implementation

The following interface only works for V10 :

interface GatewayDispatchData {
    [GatewayDispatchEvents.ChannelCreate]: GatewayChannelModifyDispatchData
    [GatewayDispatchEvents.ChannelDelete]: GatewayChannelModifyDispatchData
    [GatewayDispatchEvents.ChannelPinsUpdate]: GatewayChannelPinsUpdateDispatchData
    [GatewayDispatchEvents.ChannelUpdate]: GatewayChannelModifyDispatchData
    [GatewayDispatchEvents.GuildBanAdd]: GatewayGuildBanModifyDispatchData
    [GatewayDispatchEvents.GuildBanRemove]: GatewayGuildBanModifyDispatchData
    [GatewayDispatchEvents.GuildCreate]: GatewayGuildCreateDispatchData
    [GatewayDispatchEvents.GuildDelete]: GatewayGuildDeleteDispatchData
    [GatewayDispatchEvents.GuildEmojisUpdate]: GatewayGuildEmojisUpdateDispatchData
    [GatewayDispatchEvents.GuildIntegrationsUpdate]: GatewayGuildIntegrationsUpdateDispatchData
    [GatewayDispatchEvents.GuildMemberAdd]: GatewayGuildMemberAddDispatchData
    [GatewayDispatchEvents.GuildMemberRemove]: GatewayGuildMemberRemoveDispatchData
    [GatewayDispatchEvents.GuildMembersChunk]: GatewayGuildMembersChunkDispatchData
    [GatewayDispatchEvents.GuildMemberUpdate]: GatewayGuildMemberUpdateDispatchData
    [GatewayDispatchEvents.GuildRoleCreate]: GatewayGuildRoleModifyDispatchData
    [GatewayDispatchEvents.GuildRoleDelete]: GatewayGuildRoleDeleteDispatchData
    [GatewayDispatchEvents.GuildRoleUpdate]: GatewayChannelModifyDispatchData
    [GatewayDispatchEvents.GuildScheduledEventCreate]: GatewayGuildScheduledEventCreateDispatchData
    [GatewayDispatchEvents.GuildScheduledEventDelete]: GatewayGuildScheduledEventDeleteDispatchData
    [GatewayDispatchEvents.GuildScheduledEventUpdate]: GatewayGuildScheduledEventUpdateDispatchData
    [GatewayDispatchEvents.GuildScheduledEventUserAdd]: GatewayGuildScheduledEventUserAddDispatchData
    [GatewayDispatchEvents.GuildScheduledEventUserRemove]: GatewayGuildScheduledEventUserAddDispatchData
    [GatewayDispatchEvents.GuildStickersUpdate]: GatewayGuildStickersUpdateDispatchData
    [GatewayDispatchEvents.GuildUpdate]: GatewayGuildModifyDispatchData
    [GatewayDispatchEvents.IntegrationCreate]: GatewayIntegrationCreateDispatchData
    [GatewayDispatchEvents.IntegrationDelete]: GatewayIntegrationDeleteDispatchData
    [GatewayDispatchEvents.IntegrationUpdate]: GatewayIntegrationUpdateDispatchData
    [GatewayDispatchEvents.InteractionCreate]: GatewayInteractionCreateDispatchData
    [GatewayDispatchEvents.InviteCreate]: GatewayInviteCreateDispatchData
    [GatewayDispatchEvents.InviteDelete]: GatewayInviteDeleteDispatchData
    [GatewayDispatchEvents.MessageCreate]: GatewayMessageCreateDispatchData
    [GatewayDispatchEvents.MessageDelete]: GatewayMessageDeleteDispatchData
    [GatewayDispatchEvents.MessageDeleteBulk]: GatewayMessageDeleteBulkDispatchData
    [GatewayDispatchEvents.MessageReactionAdd]: GatewayMessageReactionAddDispatchData
    [GatewayDispatchEvents.MessageReactionRemove]: GatewayMessageReactionRemoveDispatchData
    [GatewayDispatchEvents.MessageReactionRemoveAll]: GatewayMessageReactionRemoveAllDispatchData
    [GatewayDispatchEvents.MessageReactionRemoveEmoji]: GatewayMessageReactionRemoveEmojiDispatchData
    [GatewayDispatchEvents.MessageUpdate]: GatewayMessageUpdateDispatchData
    [GatewayDispatchEvents.PresenceUpdate]: GatewayPresenceUpdateDispatchData
    [GatewayDispatchEvents.Ready]: GatewayReadyDispatchData
    [GatewayDispatchEvents.Resumed]: never
    [GatewayDispatchEvents.StageInstanceCreate]: GatewayStageInstanceCreateDispatchData
    [GatewayDispatchEvents.StageInstanceDelete]: GatewayStageInstanceDeleteDispatchData
    [GatewayDispatchEvents.StageInstanceUpdate]: GatewayStageInstanceUpdateDispatchData
    [GatewayDispatchEvents.ThreadCreate]: GatewayChannelModifyDispatchData
    [GatewayDispatchEvents.ThreadDelete]: GatewayChannelModifyDispatchData
    [GatewayDispatchEvents.ThreadListSync]: GatewayThreadListSyncDispatchData
    [GatewayDispatchEvents.ThreadMembersUpdate]: GatewayThreadMembersUpdateDispatchData
    [GatewayDispatchEvents.ThreadMemberUpdate]: GatewayThreadMemberUpdateDispatchData
    [GatewayDispatchEvents.ThreadUpdate]: GatewayChannelModifyDispatchData
    [GatewayDispatchEvents.TypingStart]: GatewayTypingStartDispatchData
    [GatewayDispatchEvents.UserUpdate]: GatewayUserUpdateDispatchData
    [GatewayDispatchEvents.VoiceServerUpdate]: GatewayVoiceServerUpdateDispatchData
    [GatewayDispatchEvents.VoiceStateUpdate]: GatewayVoiceStateUpdateDispatchData
    [GatewayDispatchEvents.WebhooksUpdate]: GatewayWebhooksUpdateDispatchData
}

Alternative solutions or implementations

type _Payload = {
    [E in GatewayDispatchEvents]: GatewayDispatchPayload & { t: E }
}

type GatewayDispatchData = {
    [E in keyof _Payload]: "d" extends keyof _Payload[E] ? _Payload[E]["d"] : never
}

Other context

No response

didinele commented 2 years ago

I've actually had the need for this myself and simply hacked it up:

import type { GatewayDispatchEvents, GatewayDispatchPayload, GatewaySendPayload } from 'discord-api-types/v10';

type _DiscordEventsMap = {
    [K in GatewayDispatchEvents]: GatewayDispatchPayload & {
        t: K;
    };
};

export type DiscordEventsMap = {
    // @ts-expect-error
    [K in keyof _DiscordEventsMap]: _DiscordEventsMap[K]['d'];
} & {
    send: GatewaySendPayload;
};

It doesn't play nicely with TSC, given the needed @ts-expect-error (as of about TS 4.8) and the fact that it needs two types (you'd think you could just inline the first one, but it does not behave the same way), but it gets the job done.

john-batch commented 2 years ago

The reason your hack requires @ts-expect-error is because some events don't have an associated payload (like ApplicationCommandPermissionsUpdate). You can fix it like this :


type _Payload = {
    [E in GatewayDispatchEvents]: GatewayDispatchPayload & { t: E }
}

type GatewayDispatchData = {
    [E in keyof _Payload]: "d" extends keyof _Payload[E] ? _Payload[E]["d"] : never
}

I edited my original post to include it as an alternative implementation.

didinele commented 2 years ago

Good catch! That explains why it only recently started occurring, thanks.

vladfrangu commented 2 years ago

Thats quite a big issue if there's events without associated payloads... PRs are more than welcome!!

john-batch commented 2 years ago

Thats quite a big issue if there's events without associated payloads... PRs are more than welcome!!

Done. (#619)