Skip to content

Commit

Permalink
feat(interaction): add isRepliable type guard (#7259)
Browse files Browse the repository at this point in the history
Co-authored-by: Almeida <almeidx@pm.me>
Co-authored-by: Rodry <38259440+ImRodry@users.noreply.github.com>
  • Loading branch information
3 people committed Jan 17, 2022
1 parent 6112767 commit da05a88
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 0 deletions.
8 changes: 8 additions & 0 deletions packages/discord.js/src/structures/Interaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,14 @@ class Interaction extends Base {
ComponentType[this.componentType] === ComponentType.SelectMenu
);
}

/**
* Indicates whether this interaction can be replied to.
* @returns {boolean}
*/
isRepliable() {
return ![InteractionType.Ping, InteractionType.ApplicationCommandAutocomplete].includes(InteractionType[this.type]);
}
}

module.exports = Interaction;
12 changes: 12 additions & 0 deletions packages/discord.js/typings/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,17 @@ export type GuildCacheMessage<Cached extends CacheType> = CacheTypeReducer<
Message | APIMessage
>;

export interface InteractionResponseFields<Cached extends CacheType = CacheType> {
reply(options: InteractionReplyOptions & { fetchReply: true }): Promise<GuildCacheMessage<Cached>>;
reply(options: string | MessagePayload | InteractionReplyOptions): Promise<void>;
deleteReply(): Promise<void>;
editReply(options: string | MessagePayload | WebhookEditMessageOptions): Promise<GuildCacheMessage<Cached>>;
deferReply(options: InteractionDeferReplyOptions & { fetchReply: true }): Promise<GuildCacheMessage<Cached>>;
deferReply(options?: InteractionDeferReplyOptions): Promise<void>;
fetchReply(): Promise<GuildCacheMessage<Cached>>;
followUp(options: string | MessagePayload | InteractionReplyOptions): Promise<GuildCacheMessage<Cached>>;
}

export abstract class CommandInteraction<Cached extends CacheType = CacheType> extends Interaction<Cached> {
public readonly command: ApplicationCommand | ApplicationCommand<{ guild: GuildResolvable }> | null;
public options: Omit<
Expand Down Expand Up @@ -1327,6 +1338,7 @@ export class Interaction<Cached extends CacheType = CacheType> extends Base {
public isUserContextMenuCommand(): this is UserContextMenuCommandInteraction<Cached>;
public isMessageComponent(): this is MessageComponentInteraction<Cached>;
public isSelectMenu(): this is SelectMenuInteraction<Cached>;
public isRepliable(): this is this & InteractionResponseFields<Cached>;
}

export class InteractionCollector<T extends Interaction> extends Collector<Snowflake, T> {
Expand Down
11 changes: 11 additions & 0 deletions packages/discord.js/typings/index.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ import {
ButtonComponent,
SelectMenuComponent,
ActionRowComponent,
InteractionResponseFields,
} from '.';
import { expectAssignable, expectDeprecated, expectNotAssignable, expectNotType, expectType } from 'tsd';

Expand Down Expand Up @@ -1124,6 +1125,16 @@ client.on('interactionCreate', async interaction => {
expectType<string | null>(interaction.options.getSubcommandGroup(booleanValue));
expectType<string | null>(interaction.options.getSubcommandGroup(false));
}

if (interaction.isRepliable()) {
expectAssignable<InteractionResponseFields>(interaction);
interaction.reply('test');
}

if (interaction.isChatInputCommand() && interaction.isRepliable()) {
expectAssignable<CommandInteraction>(interaction);
expectAssignable<InteractionResponseFields>(interaction);
}
});

declare const shard: Shard;
Expand Down

0 comments on commit da05a88

Please sign in to comment.