Skip to content

Commit

Permalink
types: Add tagged type unions for channel types (#200)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: All of the channel types are now split based on their type. As such, you will need to assert the type (either by checking it with the enum or by casting the data as the correct channel) before accessing data.
*If you encounter any missing properties due to this, please open an issue! This is a big change, and we hope nothing is missing*

Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
Co-authored-by: Antonio Román <kyradiscord@gmail.com>
  • Loading branch information
3 people committed Jan 19, 2022
1 parent 08a8b28 commit 2c1fbda
Show file tree
Hide file tree
Showing 11 changed files with 511 additions and 164 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Expand Up @@ -45,3 +45,6 @@ voice/**/*.js
voice/**/*.map
voice/**/*.d.ts
voice/**/*.mjs

# macOS files
.DS_store
134 changes: 98 additions & 36 deletions deno/payloads/v8/channel.ts
Expand Up @@ -32,35 +32,86 @@ export interface APIPartialChannel {
}

/**
* https://discord.com/developers/docs/resources/channel#channel-object-channel-structure
* This interface is used to allow easy extension for other channel types. While
* also allowing `APIPartialChannel` to be used without breaking.
*/
export interface APIChannel extends APIPartialChannel {
export interface APIChannelBase<T extends ChannelType> extends APIPartialChannel {
type: T;
}

// TODO: update when text in voice is released
export type TextChannelType = ChannelType.DM | ChannelType.GroupDM | ChannelType.GuildNews | ChannelType.GuildText;

export type GuildChannelType = Exclude<
| TextChannelType
| ChannelType.GuildVoice
| ChannelType.GuildStageVoice
| ChannelType.GuildNews
| ChannelType.GuildStore,
ChannelType.DM | ChannelType.GroupDM
>;

export interface APITextBasedChannel<T extends ChannelType> extends APIChannelBase<T> {
/**
* The id of the guild (may be missing for some channel objects received over gateway guild dispatches)
* The id of the last message sent in this channel (may not point to an existing or valid message)
*/
guild_id?: Snowflake;
last_message_id?: Snowflake | null;
}

export interface APIGuildChannel<T extends ChannelType> extends APIChannelBase<T> {
/**
* Sorting position of the channel
* The id of the guild (may be missing for some channel objects received over gateway guild dispatches)
*/
position?: number;
guild_id?: Snowflake;
/**
* Explicit permission overwrites for members and roles
*
* See https://discord.com/developers/docs/resources/channel#overwrite-object
*/
permission_overwrites?: APIOverwrite[];
/**
* The channel topic (0-1024 characters)
* Sorting position of the channel
*/
topic?: string | null;
position?: number;
/**
* ID of the parent category for a channel (each parent category can contain up to 50 channels)
*/
parent_id?: Snowflake | null;
/**
* Whether the channel is nsfw
*/
nsfw?: boolean;
}

export type GuildTextChannelType = Exclude<TextChannelType, ChannelType.DM | ChannelType.GroupDM>;

export interface APIGuildTextChannel<T extends GuildTextChannelType>
extends APITextBasedChannel<T>,
APIGuildChannel<T> {
/**
* The id of the last message sent in this channel (may not point to an existing or valid message)
* The channel topic (0-1024 characters)
*/
last_message_id?: Snowflake | null;
topic?: string | null;
/**
* When the last pinned message was pinned.
* This may be `null` in events such as `GUILD_CREATE` when a message is not pinned
*/
last_pin_timestamp?: string | null;
}

export interface APITextChannel extends APIGuildTextChannel<ChannelType.GuildText> {
/**
* Amount of seconds a user has to wait before sending another message (0-21600);
* bots, as well as users with the permission `MANAGE_MESSAGES` or `MANAGE_CHANNELS`, are unaffected
*/
rate_limit_per_user?: number;
}

export type APINewsChannel = APIGuildTextChannel<ChannelType.GuildNews>;
export type APIGuildCategoryChannel = APIGuildChannel<ChannelType.GuildCategory>;
export type APIGuildStoreChannel = APIGuildChannel<ChannelType.GuildStore>;

export interface APIVoiceChannel extends APIGuildChannel<ChannelType.GuildStageVoice | ChannelType.GuildVoice> {
/**
* The bitrate (in bits) of the voice channel
*/
Expand All @@ -70,51 +121,62 @@ export interface APIChannel extends APIPartialChannel {
*/
user_limit?: number;
/**
* Amount of seconds a user has to wait before sending another message (0-21600);
* bots, as well as users with the permission `MANAGE_MESSAGES` or `MANAGE_CHANNELS`, are unaffected
* Voice region id for the voice or stage channel, automatic when set to `null`
*
* See https://discord.com/developers/docs/resources/voice#voice-region-object
*/
rate_limit_per_user?: number;
rtc_region?: string | null;
/**
* The camera video quality mode of the voice channel, `1` when not present
*
* See https://discord.com/developers/docs/resources/channel#channel-object-video-quality-modes
*/
video_quality_mode?: VideoQualityMode;
}

interface APIDMChannelBase<T extends ChannelType> extends APITextBasedChannel<T> {
/**
* The recipients of the DM
*
* See https://discord.com/developers/docs/resources/user#user-object
*/
recipients?: APIUser[];
/**
* Icon hash
*/
icon?: string | null;
/**
* ID of the DM creator
*/
owner_id?: Snowflake;
}

export type APIDMChannel = APIDMChannelBase<ChannelType.DM>;

export interface APIGroupDMChannel extends APIDMChannelBase<ChannelType.GroupDM> {
/**
* Application id of the group DM creator if it is bot-created
*/
application_id?: Snowflake;
/**
* ID of the parent category for a channel (each parent category can contain up to 50 channels)
*/
parent_id?: Snowflake | null;
/**
* When the last pinned message was pinned.
* This may be `null` in events such as `GUILD_CREATE` when a message is not pinned
* Icon hash
*/
last_pin_timestamp?: string | null;
icon?: string | null;
/**
* Voice region id for the voice or stage channel, automatic when set to `null`
*
* See https://discord.com/developers/docs/resources/voice#voice-region-object
* ID of the DM creator
*/
rtc_region?: string | null;
owner_id?: Snowflake;
/**
* The camera video quality mode of the voice channel, `1` when not present
*
* See https://discord.com/developers/docs/resources/channel#channel-object-video-quality-modes
* The id of the last message sent in this channel (may not point to an existing or valid message)
*/
video_quality_mode?: VideoQualityMode;
last_message_id?: Snowflake | null;
}

/**
* https://discord.com/developers/docs/resources/channel#channel-object-channel-structure
*/
export type APIChannel =
| APIGroupDMChannel
| APIDMChannel
| APITextChannel
| APINewsChannel
| APIGuildStoreChannel
| APIVoiceChannel
| APIGuildCategoryChannel
| APINewsChannel;

/**
* https://discord.com/developers/docs/resources/channel#channel-object-channel-types
*/
Expand Down

0 comments on commit 2c1fbda

Please sign in to comment.