Skip to content

Commit

Permalink
feat(Channel): improve typeguards (#6957)
Browse files Browse the repository at this point in the history
Co-authored-by: Papageorgiadis Savvas <50584606+papsavas@users.noreply.github.com>
Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com>
Co-authored-by: Almeida <almeidx@pm.me>
  • Loading branch information
4 people committed Jan 12, 2022
1 parent f753882 commit 37a22e0
Show file tree
Hide file tree
Showing 12 changed files with 91 additions and 19 deletions.
2 changes: 1 addition & 1 deletion packages/discord.js/src/client/actions/MessageCreate.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class MessageCreateAction extends Action {
const client = this.client;
const channel = this.getChannel(data);
if (channel) {
if (!channel.isText()) return {};
if (!channel.isTextBased()) return {};

const existing = channel.messages.cache.get(data.id);
if (existing) return { message: existing };
Expand Down
2 changes: 1 addition & 1 deletion packages/discord.js/src/client/actions/MessageDelete.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class MessageDeleteAction extends Action {
const channel = this.getChannel(data);
let message;
if (channel) {
if (!channel.isText()) return {};
if (!channel.isTextBased()) return {};

message = this.getMessage(data, channel);
if (message) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class MessageDeleteBulkAction extends Action {
const channel = client.channels.cache.get(data.channel_id);

if (channel) {
if (!channel.isText()) return {};
if (!channel.isTextBased()) return {};

const ids = data.ids;
const messages = new Collection();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class MessageReactionAdd extends Action {

// Verify channel
const channel = this.getChannel(data);
if (!channel || !channel.isText()) return false;
if (!channel || !channel.isTextBased()) return false;

// Verify message
const message = this.getMessage(data, channel);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class MessageReactionRemove extends Action {

// Verify channel
const channel = this.getChannel(data);
if (!channel || !channel.isText()) return false;
if (!channel || !channel.isTextBased()) return false;

// Verify message
const message = this.getMessage(data, channel);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class MessageReactionRemoveAll extends Action {
handle(data) {
// Verify channel
const channel = this.getChannel(data);
if (!channel || !channel.isText()) return false;
if (!channel || !channel.isTextBased()) return false;

// Verify message
const message = this.getMessage(data, channel);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const { Events } = require('../../util/Constants');
class MessageReactionRemoveEmoji extends Action {
handle(data) {
const channel = this.getChannel(data);
if (!channel || !channel.isText()) return false;
if (!channel || !channel.isTextBased()) return false;

const message = this.getMessage(data, channel);
if (!message) return false;
Expand Down
2 changes: 1 addition & 1 deletion packages/discord.js/src/client/actions/MessageUpdate.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ class MessageUpdateAction extends Action {
handle(data) {
const channel = this.getChannel(data);
if (channel) {
if (!channel.isText()) return {};
if (!channel.isTextBased()) return {};

const { id, channel_id, guild_id, author, timestamp, type } = data;
const message = this.getMessage({ id, channel_id, guild_id, author, timestamp, type }, channel);
Expand Down
2 changes: 1 addition & 1 deletion packages/discord.js/src/client/actions/TypingStart.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class TypingStart extends Action {
const channel = this.getChannel(data);
if (!channel) return;

if (!channel.isText()) {
if (!channel.isTextBased()) {
this.client.emit(Events.WARN, `Discord sent a typing packet to a ${channel.type} channel ${channel.id}`);
return;
}
Expand Down
74 changes: 69 additions & 5 deletions packages/discord.js/src/structures/Channel.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
const { DiscordSnowflake } = require('@sapphire/snowflake');
const { ChannelType } = require('discord-api-types/v9');
const Base = require('./Base');
const { ThreadChannelTypes } = require('../util/Constants');
let CategoryChannel;
let DMChannel;
let NewsChannel;
Expand All @@ -11,7 +12,6 @@ let StoreChannel;
let TextChannel;
let ThreadChannel;
let VoiceChannel;
const { ThreadChannelTypes, VoiceBasedChannelTypes } = require('../util/Constants');

/**
* Represents any channel on Discord.
Expand Down Expand Up @@ -103,19 +103,59 @@ class Channel extends Base {
}

/**
* Indicates whether this channel is {@link TextBasedChannels text-based}.
* Indicates whether this channel is a {@link TextChannel}.
* @returns {boolean}
*/
isText() {
return 'messages' in this;
return this.type === ChannelType[ChannelType.GuildText];
}

/**
* Indicates whether this channel is {@link BaseGuildVoiceChannel voice-based}.
* Indicates whether this channel is a {@link DMChannel}.
* @returns {boolean}
*/
isDM() {
return this.type === ChannelType[ChannelType.DM];
}

/**
* Indicates whether this channel is a {@link VoiceChannel}.
* @returns {boolean}
*/
isVoice() {
return VoiceBasedChannelTypes.includes(this.type);
return this.type === ChannelType[ChannelType.GuildVoice];
}

/**
* Indicates whether this channel is a {@link PartialGroupDMChannel}.
* @returns {boolean}
*/
isGroupDM() {
return this.type === ChannelType[ChannelType.GroupDM];
}

/**
* Indicates whether this channel is a {@link CategoryChannel}.
* @returns {boolean}
*/
isCategory() {
return this.type === ChannelType[ChannelType.GuildCategory];
}

/**
* Indicates whether this channel is a {@link NewsChannel}.
* @returns {boolean}
*/
isNews() {
return this.type === ChannelType[ChannelType.GuildNews];
}

/**
* Indicates whether this channel is a {@link StoreChannel}.
* @returns {boolean}
*/
isStore() {
return this.type === ChannelType[ChannelType.GuildStore];
}

/**
Expand All @@ -126,6 +166,30 @@ class Channel extends Base {
return ThreadChannelTypes.includes(this.type);
}

/**
* Indicates whether this channel is a {@link StageChannel}.
* @returns {boolean}
*/
isStage() {
return this.type === ChannelType[ChannelType.GuildStageVoice];
}

/**
* Indicates whether this channel is {@link TextBasedChannels text-based}.
* @returns {boolean}
*/
isTextBased() {
return 'messages' in this;
}

/**
* Indicates whether this channel is {@link BaseGuildVoiceChannel voice-based}.
* @returns {boolean}
*/
isVoiceBased() {
return 'bitrate' in this;
}

static create(client, data, guild, { allowUnknownGuild, fromInteraction } = {}) {
CategoryChannel ??= require('./CategoryChannel');
DMChannel ??= require('./DMChannel');
Expand Down
4 changes: 2 additions & 2 deletions packages/discord.js/src/util/Sweepers.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ class Sweepers {
let messages = 0;

for (const channel of this.client.channels.cache.values()) {
if (!channel.isText()) continue;
if (!channel.isTextBased()) continue;

channels++;
messages += channel.messages.cache.sweep(filter);
Expand Down Expand Up @@ -168,7 +168,7 @@ class Sweepers {
let reactions = 0;

for (const channel of this.client.channels.cache.values()) {
if (!channel.isText()) continue;
if (!channel.isTextBased()) continue;
channels++;

for (const message of channel.messages.cache.values()) {
Expand Down
14 changes: 11 additions & 3 deletions packages/discord.js/typings/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -520,9 +520,17 @@ export abstract class Channel extends Base {
public type: keyof typeof ChannelType;
public delete(): Promise<this>;
public fetch(force?: boolean): Promise<this>;
public isText(): this is TextBasedChannel;
public isVoice(): this is BaseGuildVoiceChannel;
public isText(): this is TextChannel;
public isDM(): this is DMChannel;
public isVoice(): this is VoiceChannel;
public isGroupDM(): this is PartialGroupDMChannel;
public isCategory(): this is CategoryChannel;
public isNews(): this is NewsChannel;
public isStore(): this is StoreChannel;
public isThread(): this is ThreadChannel;
public isStage(): this is StageChannel;
public isTextBased(): this is TextBasedChannel;
public isVoiceBased(): this is VoiceBasedChannel;
public toString(): ChannelMention;
}

Expand Down Expand Up @@ -1051,7 +1059,7 @@ export abstract class GuildChannel extends Channel {
public setName(name: string, reason?: string): Promise<this>;
public setParent(channel: CategoryChannelResolvable | null, options?: SetParentOptions): Promise<this>;
public setPosition(position: number, options?: SetChannelPositionOptions): Promise<this>;
public isText(): this is TextChannel | NewsChannel;
public isTextBased(): this is GuildBasedChannel & TextBasedChannel;
}

export class GuildEmoji extends BaseGuildEmoji {
Expand Down

0 comments on commit 37a22e0

Please sign in to comment.