mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-19 13:03:31 +01:00
types: Inference of guild in MessageManager (#8538)
* types: better inference of message manager * types: alter helper methods Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
This commit is contained in:
102
packages/discord.js/typings/index.d.ts
vendored
102
packages/discord.js/typings/index.d.ts
vendored
@@ -123,6 +123,7 @@ import {
|
|||||||
FormattingPatterns,
|
FormattingPatterns,
|
||||||
APIEmbedProvider,
|
APIEmbedProvider,
|
||||||
AuditLogOptionsType,
|
AuditLogOptionsType,
|
||||||
|
TextChannelType,
|
||||||
} from 'discord-api-types/v10';
|
} from 'discord-api-types/v10';
|
||||||
import { ChildProcess } from 'node:child_process';
|
import { ChildProcess } from 'node:child_process';
|
||||||
import { EventEmitter } from 'node:events';
|
import { EventEmitter } from 'node:events';
|
||||||
@@ -521,7 +522,7 @@ export class BaseGuildEmoji extends Emoji {
|
|||||||
public requiresColons: boolean | null;
|
public requiresColons: boolean | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class BaseGuildTextChannel extends TextBasedChannelMixin(GuildChannel) {
|
export class BaseGuildTextChannel extends TextBasedChannelMixin(GuildChannel, true) {
|
||||||
protected constructor(guild: Guild, data?: RawGuildChannelData, client?: Client, immediatePatch?: boolean);
|
protected constructor(guild: Guild, data?: RawGuildChannelData, client?: Client, immediatePatch?: boolean);
|
||||||
public defaultAutoArchiveDuration?: ThreadAutoArchiveDuration;
|
public defaultAutoArchiveDuration?: ThreadAutoArchiveDuration;
|
||||||
public rateLimitPerUser: number | null;
|
public rateLimitPerUser: number | null;
|
||||||
@@ -1049,7 +1050,7 @@ export class DataResolver extends null {
|
|||||||
public static resolveGuildTemplateCode(data: GuildTemplateResolvable): string;
|
public static resolveGuildTemplateCode(data: GuildTemplateResolvable): string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class DMChannel extends TextBasedChannelMixin(BaseChannel, [
|
export class DMChannel extends TextBasedChannelMixin(BaseChannel, false, [
|
||||||
'bulkDelete',
|
'bulkDelete',
|
||||||
'fetchWebhooks',
|
'fetchWebhooks',
|
||||||
'createWebhook',
|
'createWebhook',
|
||||||
@@ -1675,8 +1676,8 @@ export interface MappedInteractionTypes<Cached extends boolean = boolean> {
|
|||||||
[ComponentType.SelectMenu]: SelectMenuInteraction<WrapBooleanCache<Cached>>;
|
[ComponentType.SelectMenu]: SelectMenuInteraction<WrapBooleanCache<Cached>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Message<Cached extends boolean = boolean> extends Base {
|
export class Message<InGuild extends boolean = boolean> extends Base {
|
||||||
private readonly _cacheType: Cached;
|
private readonly _cacheType: InGuild;
|
||||||
private constructor(client: Client, data: RawMessageData);
|
private constructor(client: Client, data: RawMessageData);
|
||||||
private _patch(data: RawPartialMessageData | RawMessageData): void;
|
private _patch(data: RawPartialMessageData | RawMessageData): void;
|
||||||
|
|
||||||
@@ -1684,7 +1685,7 @@ export class Message<Cached extends boolean = boolean> extends Base {
|
|||||||
public applicationId: Snowflake | null;
|
public applicationId: Snowflake | null;
|
||||||
public attachments: Collection<Snowflake, Attachment>;
|
public attachments: Collection<Snowflake, Attachment>;
|
||||||
public author: User;
|
public author: User;
|
||||||
public get channel(): If<Cached, GuildTextBasedChannel, TextBasedChannel>;
|
public get channel(): If<InGuild, GuildTextBasedChannel, TextBasedChannel>;
|
||||||
public channelId: Snowflake;
|
public channelId: Snowflake;
|
||||||
public get cleanContent(): string;
|
public get cleanContent(): string;
|
||||||
public components: ActionRow<MessageActionRowComponent>[];
|
public components: ActionRow<MessageActionRowComponent>[];
|
||||||
@@ -1698,8 +1699,8 @@ export class Message<Cached extends boolean = boolean> extends Base {
|
|||||||
public editedTimestamp: number | null;
|
public editedTimestamp: number | null;
|
||||||
public embeds: Embed[];
|
public embeds: Embed[];
|
||||||
public groupActivityApplication: ClientApplication | null;
|
public groupActivityApplication: ClientApplication | null;
|
||||||
public guildId: If<Cached, Snowflake>;
|
public guildId: If<InGuild, Snowflake>;
|
||||||
public get guild(): If<Cached, Guild>;
|
public get guild(): If<InGuild, Guild>;
|
||||||
public get hasThread(): boolean;
|
public get hasThread(): boolean;
|
||||||
public id: Snowflake;
|
public id: Snowflake;
|
||||||
public interaction: MessageInteraction | null;
|
public interaction: MessageInteraction | null;
|
||||||
@@ -1720,30 +1721,30 @@ export class Message<Cached extends boolean = boolean> extends Base {
|
|||||||
public flags: Readonly<MessageFlagsBitField>;
|
public flags: Readonly<MessageFlagsBitField>;
|
||||||
public reference: MessageReference | null;
|
public reference: MessageReference | null;
|
||||||
public awaitMessageComponent<T extends MessageComponentType>(
|
public awaitMessageComponent<T extends MessageComponentType>(
|
||||||
options?: AwaitMessageCollectorOptionsParams<T, Cached>,
|
options?: AwaitMessageCollectorOptionsParams<T, InGuild>,
|
||||||
): Promise<MappedInteractionTypes<Cached>[T]>;
|
): Promise<MappedInteractionTypes<InGuild>[T]>;
|
||||||
public awaitReactions(options?: AwaitReactionsOptions): Promise<Collection<Snowflake | string, MessageReaction>>;
|
public awaitReactions(options?: AwaitReactionsOptions): Promise<Collection<Snowflake | string, MessageReaction>>;
|
||||||
public createReactionCollector(options?: ReactionCollectorOptions): ReactionCollector;
|
public createReactionCollector(options?: ReactionCollectorOptions): ReactionCollector;
|
||||||
public createMessageComponentCollector<T extends MessageComponentType>(
|
public createMessageComponentCollector<T extends MessageComponentType>(
|
||||||
options?: MessageCollectorOptionsParams<T, Cached>,
|
options?: MessageCollectorOptionsParams<T, InGuild>,
|
||||||
): InteractionCollector<MappedInteractionTypes<Cached>[T]>;
|
): InteractionCollector<MappedInteractionTypes<InGuild>[T]>;
|
||||||
public delete(): Promise<Message>;
|
public delete(): Promise<Message<InGuild>>;
|
||||||
public edit(content: string | MessageEditOptions | MessagePayload): Promise<Message>;
|
public edit(content: string | MessageEditOptions | MessagePayload): Promise<Message<InGuild>>;
|
||||||
public equals(message: Message, rawData: unknown): boolean;
|
public equals(message: Message, rawData: unknown): boolean;
|
||||||
public fetchReference(): Promise<Message>;
|
public fetchReference(): Promise<Message<InGuild>>;
|
||||||
public fetchWebhook(): Promise<Webhook>;
|
public fetchWebhook(): Promise<Webhook>;
|
||||||
public crosspost(): Promise<Message>;
|
public crosspost(): Promise<Message<InGuild>>;
|
||||||
public fetch(force?: boolean): Promise<Message>;
|
public fetch(force?: boolean): Promise<Message<InGuild>>;
|
||||||
public pin(reason?: string): Promise<Message>;
|
public pin(reason?: string): Promise<Message<InGuild>>;
|
||||||
public react(emoji: EmojiIdentifierResolvable): Promise<MessageReaction>;
|
public react(emoji: EmojiIdentifierResolvable): Promise<MessageReaction>;
|
||||||
public removeAttachments(): Promise<Message>;
|
public removeAttachments(): Promise<Message<InGuild>>;
|
||||||
public reply(options: string | MessagePayload | ReplyMessageOptions): Promise<Message>;
|
public reply(options: string | MessagePayload | ReplyMessageOptions): Promise<Message<InGuild>>;
|
||||||
public resolveComponent(customId: string): MessageActionRowComponent | null;
|
public resolveComponent(customId: string): MessageActionRowComponent | null;
|
||||||
public startThread(options: StartThreadOptions): Promise<AnyThreadChannel>;
|
public startThread(options: StartThreadOptions): Promise<AnyThreadChannel>;
|
||||||
public suppressEmbeds(suppress?: boolean): Promise<Message>;
|
public suppressEmbeds(suppress?: boolean): Promise<Message<InGuild>>;
|
||||||
public toJSON(): unknown;
|
public toJSON(): unknown;
|
||||||
public toString(): string;
|
public toString(): string;
|
||||||
public unpin(reason?: string): Promise<Message>;
|
public unpin(reason?: string): Promise<Message<InGuild>>;
|
||||||
public inGuild(): this is Message<true> & this;
|
public inGuild(): this is Message<true> & this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2506,7 +2507,11 @@ export interface PrivateThreadChannel extends ThreadChannel {
|
|||||||
type: ChannelType.GuildPrivateThread;
|
type: ChannelType.GuildPrivateThread;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ThreadChannel extends TextBasedChannelMixin(BaseChannel, ['fetchWebhooks', 'createWebhook', 'setNSFW']) {
|
export class ThreadChannel extends TextBasedChannelMixin(BaseChannel, true, [
|
||||||
|
'fetchWebhooks',
|
||||||
|
'createWebhook',
|
||||||
|
'setNSFW',
|
||||||
|
]) {
|
||||||
private constructor(guild: Guild, data?: RawThreadChannelData, client?: Client, fromInteraction?: boolean);
|
private constructor(guild: Guild, data?: RawThreadChannelData, client?: Client, fromInteraction?: boolean);
|
||||||
public archived: boolean | null;
|
public archived: boolean | null;
|
||||||
public get archivedAt(): Date | null;
|
public get archivedAt(): Date | null;
|
||||||
@@ -2752,7 +2757,10 @@ export type ComponentData =
|
|||||||
| ModalActionRowComponentData
|
| ModalActionRowComponentData
|
||||||
| ActionRowData<MessageActionRowComponentData | ModalActionRowComponentData>;
|
| ActionRowData<MessageActionRowComponentData | ModalActionRowComponentData>;
|
||||||
|
|
||||||
export class VoiceChannel extends TextBasedChannelMixin(BaseGuildVoiceChannel, ['lastPinTimestamp', 'lastPinAt']) {
|
export class VoiceChannel extends TextBasedChannelMixin(BaseGuildVoiceChannel, true, [
|
||||||
|
'lastPinTimestamp',
|
||||||
|
'lastPinAt',
|
||||||
|
]) {
|
||||||
public videoQualityMode: VideoQualityMode | null;
|
public videoQualityMode: VideoQualityMode | null;
|
||||||
public get speakable(): boolean;
|
public get speakable(): boolean;
|
||||||
public type: ChannelType.GuildVoice;
|
public type: ChannelType.GuildVoice;
|
||||||
@@ -3518,15 +3526,22 @@ export class GuildMemberRoleManager extends DataManager<Snowflake, Role, RoleRes
|
|||||||
): Promise<GuildMember>;
|
): Promise<GuildMember>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class MessageManager extends CachedManager<Snowflake, Message, MessageResolvable> {
|
export class MessageManager<InGuild extends boolean = boolean> extends CachedManager<
|
||||||
|
Snowflake,
|
||||||
|
Message<InGuild>,
|
||||||
|
MessageResolvable
|
||||||
|
> {
|
||||||
private constructor(channel: TextBasedChannel, iterable?: Iterable<RawMessageData>);
|
private constructor(channel: TextBasedChannel, iterable?: Iterable<RawMessageData>);
|
||||||
public channel: TextBasedChannel;
|
public channel: If<InGuild, GuildTextBasedChannel, TextBasedChannel>;
|
||||||
public crosspost(message: MessageResolvable): Promise<Message>;
|
public crosspost(message: MessageResolvable): Promise<Message<InGuild>>;
|
||||||
public delete(message: MessageResolvable): Promise<void>;
|
public delete(message: MessageResolvable): Promise<void>;
|
||||||
public edit(message: MessageResolvable, options: string | MessagePayload | MessageEditOptions): Promise<Message>;
|
public edit(
|
||||||
public fetch(options: MessageResolvable | FetchMessageOptions): Promise<Message>;
|
message: MessageResolvable,
|
||||||
public fetch(options?: FetchMessagesOptions): Promise<Collection<Snowflake, Message>>;
|
options: string | MessagePayload | MessageEditOptions,
|
||||||
public fetchPinned(cache?: boolean): Promise<Collection<Snowflake, Message>>;
|
): Promise<Message<InGuild>>;
|
||||||
|
public fetch(options: MessageResolvable | FetchMessageOptions): Promise<Message<InGuild>>;
|
||||||
|
public fetch(options?: FetchMessagesOptions): Promise<Collection<Snowflake, Message<InGuild>>>;
|
||||||
|
public fetchPinned(cache?: boolean): Promise<Collection<Snowflake, Message<InGuild>>>;
|
||||||
public react(message: MessageResolvable, emoji: EmojiIdentifierResolvable): Promise<void>;
|
public react(message: MessageResolvable, emoji: EmojiIdentifierResolvable): Promise<void>;
|
||||||
public pin(message: MessageResolvable, reason?: string): Promise<void>;
|
public pin(message: MessageResolvable, reason?: string): Promise<void>;
|
||||||
public unpin(message: MessageResolvable, reason?: string): Promise<void>;
|
public unpin(message: MessageResolvable, reason?: string): Promise<void>;
|
||||||
@@ -3649,22 +3664,31 @@ export class VoiceStateManager extends CachedManager<Snowflake, VoiceState, type
|
|||||||
// to each of those classes
|
// to each of those classes
|
||||||
|
|
||||||
export type Constructable<T> = abstract new (...args: any[]) => T;
|
export type Constructable<T> = abstract new (...args: any[]) => T;
|
||||||
export function PartialTextBasedChannel<T>(Base?: Constructable<T>): Constructable<T & PartialTextBasedChannelFields>;
|
export function PartialTextBasedChannel<T>(
|
||||||
export function TextBasedChannelMixin<T, I extends keyof TextBasedChannelFields = never>(
|
|
||||||
Base?: Constructable<T>,
|
Base?: Constructable<T>,
|
||||||
ignore?: I[],
|
): Constructable<T & PartialTextBasedChannelFields<false>>;
|
||||||
): Constructable<T & Omit<TextBasedChannelFields, I>>;
|
|
||||||
|
|
||||||
export interface PartialTextBasedChannelFields {
|
export function TextBasedChannelMixin<
|
||||||
send(options: string | MessagePayload | MessageOptions): Promise<Message>;
|
T,
|
||||||
|
InGuild extends boolean = boolean,
|
||||||
|
I extends keyof TextBasedChannelFields<InGuild> = never,
|
||||||
|
>(
|
||||||
|
Base?: Constructable<T>,
|
||||||
|
inGuild?: InGuild,
|
||||||
|
ignore?: I[],
|
||||||
|
): Constructable<T & Omit<TextBasedChannelFields<InGuild>, I>>;
|
||||||
|
|
||||||
|
export interface PartialTextBasedChannelFields<InGuild extends boolean = boolean> {
|
||||||
|
send(options: string | MessagePayload | MessageOptions): Promise<Message<InGuild>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TextBasedChannelFields extends PartialTextBasedChannelFields {
|
export interface TextBasedChannelFields<InGuild extends boolean = boolean>
|
||||||
|
extends PartialTextBasedChannelFields<InGuild> {
|
||||||
lastMessageId: Snowflake | null;
|
lastMessageId: Snowflake | null;
|
||||||
get lastMessage(): Message | null;
|
get lastMessage(): Message | null;
|
||||||
lastPinTimestamp: number | null;
|
lastPinTimestamp: number | null;
|
||||||
get lastPinAt(): Date | null;
|
get lastPinAt(): Date | null;
|
||||||
messages: MessageManager;
|
messages: MessageManager<InGuild>;
|
||||||
awaitMessageComponent<T extends MessageComponentType>(
|
awaitMessageComponent<T extends MessageComponentType>(
|
||||||
options?: AwaitMessageCollectorOptionsParams<T, true>,
|
options?: AwaitMessageCollectorOptionsParams<T, true>,
|
||||||
): Promise<MappedInteractionTypes[T]>;
|
): Promise<MappedInteractionTypes[T]>;
|
||||||
@@ -5521,7 +5545,7 @@ export type Channel =
|
|||||||
| AnyThreadChannel
|
| AnyThreadChannel
|
||||||
| VoiceChannel;
|
| VoiceChannel;
|
||||||
|
|
||||||
export type TextBasedChannel = Extract<Channel, { messages: MessageManager }>;
|
export type TextBasedChannel = Exclude<Extract<Channel, { type: TextChannelType }>, PartialGroupDMChannel>;
|
||||||
|
|
||||||
export type TextBasedChannelTypes = TextBasedChannel['type'];
|
export type TextBasedChannelTypes = TextBasedChannel['type'];
|
||||||
|
|
||||||
|
|||||||
@@ -1049,11 +1049,11 @@ declare const user: User;
|
|||||||
declare const guildMember: GuildMember;
|
declare const guildMember: GuildMember;
|
||||||
|
|
||||||
// Test whether the structures implement send
|
// Test whether the structures implement send
|
||||||
expectType<TextBasedChannelFields['send']>(dmChannel.send);
|
expectType<TextBasedChannelFields<false>['send']>(dmChannel.send);
|
||||||
expectType<TextBasedChannelFields['send']>(threadChannel.send);
|
expectType<TextBasedChannelFields<true>['send']>(threadChannel.send);
|
||||||
expectType<TextBasedChannelFields['send']>(newsChannel.send);
|
expectType<TextBasedChannelFields<true>['send']>(newsChannel.send);
|
||||||
expectType<TextBasedChannelFields['send']>(textChannel.send);
|
expectType<TextBasedChannelFields<true>['send']>(textChannel.send);
|
||||||
expectType<TextBasedChannelFields['send']>(voiceChannel.send);
|
expectType<TextBasedChannelFields<true>['send']>(voiceChannel.send);
|
||||||
expectAssignable<PartialTextBasedChannelFields>(user);
|
expectAssignable<PartialTextBasedChannelFields>(user);
|
||||||
expectAssignable<PartialTextBasedChannelFields>(guildMember);
|
expectAssignable<PartialTextBasedChannelFields>(guildMember);
|
||||||
|
|
||||||
@@ -1190,6 +1190,34 @@ declare const guildChannelManager: GuildChannelManager;
|
|||||||
expectType<Promise<Collection<Snowflake, AnyChannel>>>(guildChannelManager.fetch());
|
expectType<Promise<Collection<Snowflake, AnyChannel>>>(guildChannelManager.fetch());
|
||||||
expectType<Promise<Collection<Snowflake, AnyChannel>>>(guildChannelManager.fetch(undefined, {}));
|
expectType<Promise<Collection<Snowflake, AnyChannel>>>(guildChannelManager.fetch(undefined, {}));
|
||||||
expectType<Promise<AnyChannel | null>>(guildChannelManager.fetch('0'));
|
expectType<Promise<AnyChannel | null>>(guildChannelManager.fetch('0'));
|
||||||
|
|
||||||
|
const channel = guildChannelManager.cache.first()!;
|
||||||
|
|
||||||
|
if (channel.isTextBased()) {
|
||||||
|
const { messages } = channel;
|
||||||
|
const message = await messages.fetch('123');
|
||||||
|
expectType<MessageManager<true>>(messages);
|
||||||
|
expectType<Promise<Message<true>>>(messages.crosspost('1234567890'));
|
||||||
|
expectType<Promise<Message<true>>>(messages.edit('1234567890', 'text'));
|
||||||
|
expectType<Promise<Message<true>>>(messages.fetch('1234567890'));
|
||||||
|
expectType<Promise<Collection<Snowflake, Message<true>>>>(messages.fetchPinned());
|
||||||
|
expectType<Guild>(message.guild);
|
||||||
|
expectType<Snowflake>(message.guildId);
|
||||||
|
expectType<GuildTextBasedChannel>(message.channel.messages.channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const { messages } = dmChannel;
|
||||||
|
const message = await messages.fetch('123');
|
||||||
|
expectType<MessageManager<false>>(messages);
|
||||||
|
expectType<Promise<Message<false>>>(messages.crosspost('1234567890')); // This shouldn't even exist!
|
||||||
|
expectType<Promise<Message<false>>>(messages.edit('1234567890', 'text'));
|
||||||
|
expectType<Promise<Message<false>>>(messages.fetch('1234567890'));
|
||||||
|
expectType<Promise<Collection<Snowflake, Message<false>>>>(messages.fetchPinned());
|
||||||
|
expectType<null>(message.guild);
|
||||||
|
expectType<null>(message.guildId);
|
||||||
|
expectType<TextBasedChannel>(message.channel.messages.channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
declare const messageManager: MessageManager;
|
declare const messageManager: MessageManager;
|
||||||
|
|||||||
Reference in New Issue
Block a user