diff --git a/packages/discord.js/.eslintrc.json b/packages/discord.js/.eslintrc.json index c76bf9863..ecfad0981 100644 --- a/packages/discord.js/.eslintrc.json +++ b/packages/discord.js/.eslintrc.json @@ -204,6 +204,9 @@ { "files": ["typings/*.ts", "scripts/*.mjs"], "parser": "@typescript-eslint/parser", + "parserOptions": { + "project": "./tsconfig.json" + }, "plugins": ["@typescript-eslint"], "rules": { "@typescript-eslint/naming-convention": [ @@ -216,6 +219,33 @@ "match": true } } + ], + "no-restricted-syntax": [ + 2, + { + "selector": "MethodDefinition[key.name!=on][key.name!=once][key.name!=off] > TSEmptyBodyFunctionExpression > Identifier :not(TSTypeOperator[operator=readonly]) > TSArrayType", + "message": "Array parameters on methods must be readonly" + }, + { + "selector": "MethodDefinition > TSEmptyBodyFunctionExpression > Identifier TSTypeReference > Identifier[name=Collection]", + "message": "Parameters of type Collection on methods must use ReadonlyCollection" + }, + { + "selector": "TSDeclareFunction > Identifier :not(TSTypeOperator[operator=readonly]) > TSArrayType", + "message": "Array parameters on functions must be readonly" + }, + { + "selector": "TSDeclareFunction Identifier TSTypeReference > Identifier[name=Collection]", + "message": "Parameters of type Collection on functions must use ReadonlyCollection" + }, + { + "selector": "TSInterfaceDeclaration TSPropertySignature :not(TSTypeOperator[operator=readonly]) > TSArrayType", + "message": "Array properties on interfaces must be readonly" + }, + { + "selector": "TSInterfaceDeclaration TSPropertySignature TSTypeReference > Identifier[name=Collection]", + "message": "Interface properties of type Collection must use ReadonlyCollection" + } ] } } diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index 597c16a8c..0ed374d28 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -305,7 +305,7 @@ export type ActionRowComponent = MessageActionRowComponent | ModalActionRowCompo export interface ActionRowData | ActionRowComponentData> extends BaseComponentData { - components: ComponentType[]; + components: readonly ComponentType[]; } export class ActionRowBuilder< @@ -395,23 +395,26 @@ export class AutoModerationRule extends Base { public delete(reason?: string): Promise; public setName(name: string, reason?: string): Promise; public setEventType(eventType: AutoModerationRuleEventType, reason?: string): Promise; - public setKeywordFilter(keywordFilter: string[], reason?: string): Promise; - public setRegexPatterns(regexPatterns: string[], reason?: string): Promise; - public setPresets(presets: AutoModerationRuleKeywordPresetType[], reason?: string): Promise; - public setAllowList(allowList: string[], reason?: string): Promise; + public setKeywordFilter(keywordFilter: readonly string[], reason?: string): Promise; + public setRegexPatterns(regexPatterns: readonly string[], reason?: string): Promise; + public setPresets( + presets: readonly AutoModerationRuleKeywordPresetType[], + reason?: string, + ): Promise; + public setAllowList(allowList: readonly string[], reason?: string): Promise; public setMentionTotalLimit(mentionTotalLimit: number, reason?: string): Promise; public setMentionRaidProtectionEnabled( mentionRaidProtectionEnabled: boolean, reason?: string, ): Promise; - public setActions(actions: AutoModerationActionOptions[], reason?: string): Promise; + public setActions(actions: readonly AutoModerationActionOptions[], reason?: string): Promise; public setEnabled(enabled?: boolean, reason?: string): Promise; public setExemptRoles( - roles: Collection | RoleResolvable[], + roles: ReadonlyCollection | readonly RoleResolvable[], reason?: string, ): Promise; public setExemptChannels( - channels: Collection | GuildChannelResolvable[], + channels: ReadonlyCollection | readonly GuildChannelResolvable[], reason?: string, ): Promise; } @@ -469,14 +472,19 @@ export class ApplicationCommand extends Base { defaultMemberPermissions: PermissionResolvable | null, ): Promise>; public setDMPermission(dmPermission?: boolean): Promise>; - public setOptions(options: ApplicationCommandOptionData[]): Promise>; + public setOptions( + options: readonly ApplicationCommandOptionData[], + ): Promise>; public equals( command: ApplicationCommand | ApplicationCommandData | RawApplicationCommandData, enforceOptionOrder?: boolean, ): boolean; public static optionsEqual( - existing: ApplicationCommandOption[], - options: ApplicationCommandOption[] | ApplicationCommandOptionData[] | APIApplicationCommandOption[], + existing: readonly ApplicationCommandOption[], + options: + | readonly ApplicationCommandOption[] + | readonly ApplicationCommandOptionData[] + | readonly APIApplicationCommandOption[], enforceOptionOrder?: boolean, ): boolean; private static _optionEquals( @@ -862,7 +870,7 @@ export interface EmbedData { thumbnail?: EmbedAssetData; provider?: APIEmbedProvider; author?: EmbedAuthorData; - fields?: APIEmbedField[]; + fields?: readonly APIEmbedField[]; video?: EmbedAssetData; } @@ -1062,7 +1070,7 @@ export class ClientApplication extends Application { public fetchRoleConnectionMetadataRecords(): Promise; public fetchSKUs(): Promise>; public editRoleConnectionMetadataRecords( - records: ApplicationRoleConnectionMetadataEditOptions[], + records: readonly ApplicationRoleConnectionMetadataEditOptions[], ): Promise; } @@ -1080,10 +1088,10 @@ export class ClientUser extends User { public edit(options: ClientUserEditOptions): Promise; public setActivity(options?: ActivityOptions): ClientPresence; public setActivity(name: string, options?: Omit): ClientPresence; - public setAFK(afk?: boolean, shardId?: number | number[]): ClientPresence; + public setAFK(afk?: boolean, shardId?: number | readonly number[]): ClientPresence; public setAvatar(avatar: BufferResolvable | Base64Resolvable | null): Promise; public setPresence(data: PresenceData): ClientPresence; - public setStatus(status: PresenceStatusData, shardId?: number | number[]): ClientPresence; + public setStatus(status: PresenceStatusData, shardId?: number | readonly number[]): ClientPresence; public setUsername(username: string): Promise; } @@ -1109,7 +1117,7 @@ export interface CollectorEventTypes collect: [Value, ...Extras]; ignore: [Value, ...Extras]; dispose: [Value, ...Extras]; - end: [collected: Collection, reason: string]; + end: [collected: ReadonlyCollection, reason: string]; } export abstract class Collector extends EventEmitter { @@ -1175,13 +1183,13 @@ export class AutocompleteInteraction exten public inGuild(): this is AutocompleteInteraction<'raw' | 'cached'>; public inCachedGuild(): this is AutocompleteInteraction<'cached'>; public inRawGuild(): this is AutocompleteInteraction<'raw'>; - public respond(options: ApplicationCommandOptionChoiceData[]): Promise; + public respond(options: readonly ApplicationCommandOptionChoiceData[]): Promise; } export class CommandInteractionOptionResolver { private constructor( client: Client, - options: CommandInteractionOption[], + options: readonly CommandInteractionOption[], resolved: CommandInteractionResolvedData, ); public readonly client: Client; @@ -1192,14 +1200,14 @@ export class CommandInteractionOptionResolver; private _getTypedOption( name: string, - allowedTypes: ApplicationCommandOptionType[], - properties: (keyof ApplicationCommandOption)[], + allowedTypes: readonly ApplicationCommandOptionType[], + properties: readonly (keyof ApplicationCommandOption)[], required: boolean, ): CommandInteractionOption | null; @@ -1923,11 +1931,17 @@ export class InteractionCollector exte public empty(): void; public dispose(interaction: Interaction): Snowflake; public on(event: 'collect' | 'dispose' | 'ignore', listener: (interaction: Interaction) => void): this; - public on(event: 'end', listener: (collected: Collection, reason: string) => void): this; + public on( + event: 'end', + listener: (collected: ReadonlyCollection, reason: string) => void, + ): this; public on(event: string, listener: (...args: any[]) => void): this; public once(event: 'collect' | 'dispose' | 'ignore', listener: (interaction: Interaction) => void): this; - public once(event: 'end', listener: (collected: Collection, reason: string) => void): this; + public once( + event: 'end', + listener: (collected: ReadonlyCollection, reason: string) => void, + ): this; public once(event: string, listener: (...args: any[]) => void): this; } @@ -2268,8 +2282,8 @@ export class MessageFlagsBitField extends BitField { export class MessageMentions { private constructor( message: Message, - users: APIUser[] | Collection, - roles: Snowflake[] | Collection, + users: readonly APIUser[] | ReadonlyCollection, + roles: readonly Snowflake[] | ReadonlyCollection, everyone: boolean, repliedUser?: APIUser | User, ); @@ -2354,7 +2368,7 @@ export class MessageReaction { export interface ModalComponentData { customId: string; title: string; - components: ( + components: readonly ( | JSONEncodable> | ActionRowData )[]; @@ -2372,11 +2386,11 @@ export interface TextInputModalData extends BaseModalData { export interface ActionRowModalData { type: ComponentType.ActionRow; - components: TextInputModalData[]; + components: readonly TextInputModalData[]; } export class ModalSubmitFields { - constructor(components: ModalActionRowComponent[][]); + constructor(components: readonly (readonly ModalActionRowComponent[])[]); public components: ActionRowModalData[]; public fields: Collection; public getField(customId: string, type: Type): { type: Type } & TextInputModalData; @@ -2502,7 +2516,7 @@ export abstract class ThreadOnlyChannel extends GuildChannel { public nsfw: boolean; public topic: string | null; public defaultSortOrder: SortOrderType | null; - public setAvailableTags(tags: GuildForumTagData[], reason?: string): Promise; + public setAvailableTags(tags: readonly GuildForumTagData[], reason?: string): Promise; public setDefaultReactionEmoji(emojiId: DefaultReactionEmoji | null, reason?: string): Promise; public setDefaultThreadRateLimitPerUser(rateLimit: number, reason?: string): Promise; public createInvite(options?: InviteCreateOptions): Promise; @@ -2591,7 +2605,10 @@ export class ReactionCollector extends Collector void, ): this; - public on(event: 'end', listener: (collected: Collection, reason: string) => void): this; + public on( + event: 'end', + listener: (collected: ReadonlyCollection, reason: string) => void, + ): this; public on(event: string, listener: (...args: any[]) => void): this; public once( @@ -2600,7 +2617,7 @@ export class ReactionCollector extends Collector, reason: string) => void, + listener: (collected: ReadonlyCollection, reason: string) => void, ): this; public once(event: string, listener: (...args: any[]) => void): this; } @@ -2883,8 +2900,8 @@ export class ShardClientUtil { export class ShardingManager extends EventEmitter { public constructor(file: string, options?: ShardingManagerOptions); - private _performOnShards(method: string, args: unknown[]): Promise; - private _performOnShards(method: string, args: unknown[], shard: number): Promise; + private _performOnShards(method: string, args: readonly unknown[]): Promise; + private _performOnShards(method: string, args: readonly unknown[], shard: number): Promise; public file: string; public respawn: boolean; @@ -3208,7 +3225,7 @@ export class ThreadChannel extends BaseCha public setLocked(locked?: boolean, reason?: string): Promise; public setName(name: string, reason?: string): Promise; // The following 3 methods can only be run on forum threads. - public setAppliedTags(appliedTags: Snowflake[], reason?: string): Promise>; + public setAppliedTags(appliedTags: readonly Snowflake[], reason?: string): Promise>; public pin(reason?: string): Promise>; public unpin(reason?: string): Promise>; public toString(): ChannelMention; @@ -3324,7 +3341,7 @@ export class UserFlagsBitField extends BitField { export function basename(path: string, ext?: string): string; export function cleanContent(str: string, channel: TextBasedChannel): string; export function discordSort( - collection: Collection, + collection: ReadonlyCollection, ): Collection; export function cleanCodeBlockContent(text: string): string; export function fetchRecommendedShardCount(token: string, options?: FetchRecommendedShardCountOptions): Promise; @@ -3334,7 +3351,13 @@ export function makeError(obj: MakeErrorOptions): Error; /** @internal */ export function makePlainError(err: Error): MakeErrorOptions; /** @internal */ -export function moveElementInArray(array: unknown[], element: unknown, newIndex: number, offset?: boolean): number; +export function moveElementInArray( + // eslint-disable-next-line no-restricted-syntax + array: unknown[], + element: unknown, + newIndex: number, + offset?: boolean, +): number; export function parseEmoji(text: string): PartialEmoji | null; export function resolveColor(color: ColorResolvable): number; /** @internal */ @@ -3347,7 +3370,7 @@ export function setPosition( item: Item, position: number, relative: boolean, - sorted: Collection, + sorted: ReadonlyCollection, client: Client, route: string, reason?: string, @@ -4146,7 +4169,7 @@ export class GuildApplicationCommandManager extends ApplicationCommandManager>; - public set(commands: ApplicationCommandDataResolvable[]): Promise>; + public set(commands: readonly ApplicationCommandDataResolvable[]): Promise>; } export type MappedGuildChannelTypes = { @@ -4204,11 +4227,11 @@ export class GuildEmojiRoleManager extends DataManager, + roleOrRoles: RoleResolvable | readonly RoleResolvable[] | ReadonlyCollection, ): Promise; - public set(roles: readonly RoleResolvable[] | Collection): Promise; + public set(roles: readonly RoleResolvable[] | ReadonlyCollection): Promise; public remove( - roleOrRoles: RoleResolvable | readonly RoleResolvable[] | Collection, + roleOrRoles: RoleResolvable | readonly RoleResolvable[] | ReadonlyCollection, ): Promise; } @@ -4319,12 +4342,15 @@ export class GuildMemberRoleManager extends DataManager, + roleOrRoles: RoleResolvable | readonly RoleResolvable[] | ReadonlyCollection, + reason?: string, + ): Promise; + public set( + roles: readonly RoleResolvable[] | ReadonlyCollection, reason?: string, ): Promise; - public set(roles: readonly RoleResolvable[] | Collection, reason?: string): Promise; public remove( - roleOrRoles: RoleResolvable | readonly RoleResolvable[] | Collection, + roleOrRoles: RoleResolvable | readonly RoleResolvable[] | ReadonlyCollection, reason?: string, ): Promise; } @@ -4365,7 +4391,7 @@ export class PermissionOverwriteManager extends CachedManager< > { private constructor(client: Client, iterable?: Iterable); public set( - overwrites: readonly OverwriteResolvable[] | Collection, + overwrites: readonly OverwriteResolvable[] | ReadonlyCollection, reason?: string, ): Promise; private upsert( @@ -4575,7 +4601,7 @@ export interface ActivityOptions { export interface AddGuildMemberOptions { accessToken: string; nick?: string; - roles?: Collection | RoleResolvable[]; + roles?: ReadonlyCollection | readonly RoleResolvable[]; mute?: boolean; deaf?: boolean; force?: boolean; @@ -4909,10 +4935,10 @@ export interface AutoModerationActionMetadata { } export interface AutoModerationTriggerMetadata { - keywordFilter: string[]; - regexPatterns: string[]; - presets: AutoModerationRuleKeywordPresetType[]; - allowList: string[]; + keywordFilter: readonly string[]; + regexPatterns: readonly string[]; + presets: readonly AutoModerationRuleKeywordPresetType[]; + allowList: readonly string[]; mentionTotalLimit: number | null; mentionRaidProtectionEnabled: boolean; } @@ -4929,11 +4955,11 @@ export interface AwaitModalSubmitOptions; + permissionOverwrites?: readonly OverwriteResolvable[] | ReadonlyCollection; topic?: string; type?: CategoryChannelType; nsfw?: boolean; @@ -5028,7 +5054,7 @@ export interface CategoryCreateChannelOptions { rtcRegion?: string; videoQualityMode?: VideoQualityMode; defaultThreadRateLimitPerUser?: number; - availableTags?: GuildForumTagData[]; + availableTags?: readonly GuildForumTagData[]; defaultReactionEmoji?: DefaultReactionEmoji; defaultAutoArchiveDuration?: ThreadAutoArchiveDuration; defaultSortOrder?: SortOrderType; @@ -5102,9 +5128,9 @@ export interface ClientEvents { guildMemberAvailable: [member: GuildMember | PartialGuildMember]; guildMemberRemove: [member: GuildMember | PartialGuildMember]; guildMembersChunk: [ - members: Collection, + members: ReadonlyCollection, guild: Guild, - data: { index: number; count: number; notFound: unknown[]; nonce: string | undefined }, + data: { index: number; count: number; notFound: readonly unknown[]; nonce: string | undefined }, ]; guildMemberUpdate: [oldMember: GuildMember | PartialGuildMember, newMember: GuildMember]; guildUpdate: [oldGuild: Guild, newGuild: Guild]; @@ -5114,10 +5140,13 @@ export interface ClientEvents { messageDelete: [message: Message | PartialMessage]; messageReactionRemoveAll: [ message: Message | PartialMessage, - reactions: Collection, + reactions: ReadonlyCollection, ]; messageReactionRemoveEmoji: [reaction: MessageReaction | PartialMessageReaction]; - messageDeleteBulk: [messages: Collection, channel: GuildTextBasedChannel]; + messageDeleteBulk: [ + messages: ReadonlyCollection, + channel: GuildTextBasedChannel, + ]; messageReactionAdd: [reaction: MessageReaction | PartialMessageReaction, user: User | PartialUser]; messageReactionRemove: [reaction: MessageReaction | PartialMessageReaction, user: User | PartialUser]; messageUpdate: [oldMessage: Message | PartialMessage, newMessage: Message | PartialMessage]; @@ -5129,11 +5158,11 @@ export interface ClientEvents { roleUpdate: [oldRole: Role, newRole: Role]; threadCreate: [thread: AnyThreadChannel, newlyCreated: boolean]; threadDelete: [thread: AnyThreadChannel]; - threadListSync: [threads: Collection, guild: Guild]; + threadListSync: [threads: ReadonlyCollection, guild: Guild]; threadMemberUpdate: [oldMember: ThreadMember, newMember: ThreadMember]; threadMembersUpdate: [ - addedMembers: Collection, - removedMembers: Collection, + addedMembers: ReadonlyCollection, + removedMembers: ReadonlyCollection, thread: AnyThreadChannel, ]; threadUpdate: [oldThread: AnyThreadChannel, newThread: AnyThreadChannel]; @@ -5170,12 +5199,12 @@ export interface ClientFetchInviteOptions { } export interface ClientOptions { - shards?: number | number[] | 'auto'; + shards?: number | readonly number[] | 'auto'; shardCount?: number; closeTimeout?: number; makeCache?: CacheFactory; allowedMentions?: MessageMentionOptions; - partials?: Partials[]; + partials?: readonly Partials[]; failIfNotExists?: boolean; presence?: PresenceData; intents: BitFieldResolvable; @@ -5234,7 +5263,7 @@ export interface CommandInteractionOption value?: string | number | boolean; focused?: boolean; autocomplete?: boolean; - options?: CommandInteractionOption[]; + options?: readonly CommandInteractionOption[]; user?: User; member?: CacheTypeReducer; channel?: CacheTypeReducer; @@ -5244,12 +5273,12 @@ export interface CommandInteractionOption } export interface CommandInteractionResolvedData { - users?: Collection; - members?: Collection>; - roles?: Collection>; - channels?: Collection>; - messages?: Collection>; - attachments?: Collection; + users?: ReadonlyCollection; + members?: ReadonlyCollection>; + roles?: ReadonlyCollection>; + channels?: ReadonlyCollection>; + messages?: ReadonlyCollection>; + attachments?: ReadonlyCollection; } export interface AutocompleteFocusedOption extends Pick { @@ -5498,8 +5527,8 @@ export interface FetchChannelOptions extends BaseFetchOptions { } export interface FetchedThreads { - threads: Collection; - members: Collection; + threads: ReadonlyCollection; + members: ReadonlyCollection; } export interface FetchedThreadsMore extends FetchedThreads { @@ -5546,7 +5575,7 @@ export interface FetchMemberOptions extends BaseFetchOptions { } export interface FetchMembersOptions { - user?: UserResolvable | UserResolvable[]; + user?: UserResolvable | readonly UserResolvable[]; query?: string; limit?: number; withPresences?: boolean; @@ -5752,10 +5781,10 @@ export interface AutoModerationRuleCreateOptions { eventType: AutoModerationRuleEventType; triggerType: AutoModerationRuleTriggerType; triggerMetadata?: AutoModerationTriggerMetadataOptions; - actions: AutoModerationActionOptions[]; + actions: readonly AutoModerationActionOptions[]; enabled?: boolean; - exemptRoles?: Collection | RoleResolvable[]; - exemptChannels?: Collection | GuildChannelResolvable[]; + exemptRoles?: ReadonlyCollection | readonly RoleResolvable[]; + exemptChannels?: ReadonlyCollection | readonly GuildChannelResolvable[]; reason?: string; } @@ -5799,11 +5828,11 @@ export interface GuildChannelEditOptions { parent?: CategoryChannelResolvable | null; rateLimitPerUser?: number; lockPermissions?: boolean; - permissionOverwrites?: readonly OverwriteResolvable[] | Collection; + permissionOverwrites?: readonly OverwriteResolvable[] | ReadonlyCollection; defaultAutoArchiveDuration?: ThreadAutoArchiveDuration; rtcRegion?: string | null; videoQualityMode?: VideoQualityMode | null; - availableTags?: GuildForumTagData[]; + availableTags?: readonly GuildForumTagData[]; defaultReactionEmoji?: DefaultReactionEmoji | null; defaultThreadRateLimitPerUser?: number; flags?: ChannelFlagsResolvable; @@ -5823,8 +5852,8 @@ export interface GuildCreateOptions { verificationLevel?: GuildVerificationLevel; defaultMessageNotifications?: GuildDefaultMessageNotifications; explicitContentFilter?: GuildExplicitContentFilter; - roles?: PartialRoleData[]; - channels?: PartialChannelData[]; + roles?: readonly PartialRoleData[]; + channels?: readonly PartialChannelData[]; afkChannelId?: Snowflake | number; afkTimeout?: number; systemChannelId?: Snowflake | number; @@ -5854,7 +5883,7 @@ export interface GuildEditOptions { publicUpdatesChannel?: TextChannelResolvable | null; safetyAlertsChannel?: TextChannelResolvable | null; preferredLocale?: Locale | null; - features?: `${GuildFeature}`[]; + features?: readonly `${GuildFeature}`[]; description?: string | null; premiumProgressBarEnabled?: boolean; reason?: string; @@ -5863,13 +5892,13 @@ export interface GuildEditOptions { export interface GuildEmojiCreateOptions { attachment: BufferResolvable | Base64Resolvable; name: string; - roles?: Collection | RoleResolvable[]; + roles?: ReadonlyCollection | readonly RoleResolvable[]; reason?: string; } export interface GuildEmojiEditOptions { name?: string; - roles?: Collection | RoleResolvable[]; + roles?: ReadonlyCollection | readonly RoleResolvable[]; reason?: string; } @@ -5890,7 +5919,7 @@ export interface GuildStickerEditOptions { export interface GuildMemberEditOptions { nick?: string | null; - roles?: Collection | readonly RoleResolvable[]; + roles?: ReadonlyCollection | readonly RoleResolvable[]; mute?: boolean; deaf?: boolean; channel?: GuildVoiceChannelResolvable | null; @@ -5908,7 +5937,7 @@ export interface GuildPruneMembersOptions { days?: number; dry?: boolean; reason?: string; - roles?: RoleResolvable[]; + roles?: readonly RoleResolvable[]; } export interface GuildWidgetSettingsData { @@ -6074,7 +6103,7 @@ export interface InviteGenerationOptions { permissions?: PermissionResolvable; guild?: GuildResolvable; disableGuildSelect?: boolean; - scopes: OAuth2Scopes[]; + scopes: readonly OAuth2Scopes[]; } export type GuildInvitableChannelResolvable = @@ -6194,9 +6223,9 @@ export interface MessageMentionsHasOptions { } export interface MessageMentionOptions { - parse?: MessageMentionTypes[]; - roles?: Snowflake[]; - users?: Snowflake[]; + parse?: readonly MessageMentionTypes[]; + roles?: readonly Snowflake[]; + users?: readonly Snowflake[]; repliedUser?: boolean; } @@ -6204,9 +6233,9 @@ export type MessageMentionTypes = 'roles' | 'users' | 'everyone'; export interface BaseMessageOptions { content?: string; - embeds?: (JSONEncodable | APIEmbed)[]; + embeds?: readonly (JSONEncodable | APIEmbed)[]; allowedMentions?: MessageMentionOptions; - files?: ( + files?: readonly ( | BufferResolvable | Stream | JSONEncodable @@ -6214,7 +6243,7 @@ export interface BaseMessageOptions { | AttachmentBuilder | AttachmentPayload )[]; - components?: ( + components?: readonly ( | JSONEncodable> | ActionRowData | APIActionRowComponent @@ -6226,7 +6255,7 @@ export interface MessageCreateOptions extends BaseMessageOptions { nonce?: string | number; enforceNonce?: boolean; reply?: ReplyOptions; - stickers?: StickerResolvable[]; + stickers?: readonly StickerResolvable[]; flags?: BitFieldResolvable< Extract, MessageFlags.SuppressEmbeds | MessageFlags.SuppressNotifications @@ -6243,7 +6272,7 @@ export interface MessageEditAttachmentData { export interface MessageEditOptions extends Omit { content?: string | null; - attachments?: (Attachment | MessageEditAttachmentData)[]; + attachments?: readonly (Attachment | MessageEditAttachmentData)[]; flags?: BitFieldResolvable, MessageFlags.SuppressEmbeds>; } @@ -6267,7 +6296,7 @@ export interface BaseSelectMenuComponentData extends BaseComponentData { export interface StringSelectMenuComponentData extends BaseSelectMenuComponentData { type: ComponentType.StringSelect; - options: SelectMenuComponentOptionData[]; + options: readonly SelectMenuComponentOptionData[]; } export interface UserSelectMenuComponentData extends BaseSelectMenuComponentData { @@ -6284,7 +6313,7 @@ export interface MentionableSelectMenuComponentData extends BaseSelectMenuCompon export interface ChannelSelectMenuComponentData extends BaseSelectMenuComponentData { type: ComponentType.ChannelSelect; - channelTypes?: ChannelType[]; + channelTypes?: readonly ChannelType[]; } export interface MessageSelectOption { @@ -6364,8 +6393,8 @@ export interface PartialRecipient { export interface PresenceData { status?: PresenceStatusData; afk?: boolean; - activities?: ActivitiesOptions[]; - shardId?: number | number[]; + activities?: readonly ActivitiesOptions[]; + shardId?: number | readonly number[]; } export type PresenceResolvable = Presence | UserResolvable | Snowflake; @@ -6381,7 +6410,7 @@ export interface PartialChannelData { userLimit?: number; rtcRegion?: string | null; videoQualityMode?: VideoQualityMode; - permissionOverwrites?: PartialOverwriteData[]; + permissionOverwrites?: readonly PartialOverwriteData[]; rateLimitPerUser?: number; } @@ -6528,13 +6557,13 @@ export type ShardingManagerMode = 'process' | 'worker'; export interface ShardingManagerOptions { totalShards?: number | 'auto'; - shardList?: number[] | 'auto'; + shardList?: readonly number[] | 'auto'; mode?: ShardingManagerMode; respawn?: boolean; silent?: boolean; - shardArgs?: string[]; + shardArgs?: readonly string[]; token?: string; - execArgv?: string[]; + execArgv?: readonly string[]; } export { Snowflake }; @@ -6661,7 +6690,7 @@ export interface GuildTextThreadCreateOptions extends StartTh export interface GuildForumThreadCreateOptions extends StartThreadOptions { message: GuildForumThreadMessageCreateOptions | MessagePayload; - appliedTags?: Snowflake[]; + appliedTags?: readonly Snowflake[]; } export interface ThreadEditOptions { @@ -6671,7 +6700,7 @@ export interface ThreadEditOptions { rateLimitPerUser?: number; locked?: boolean; invitable?: boolean; - appliedTags?: Snowflake[]; + appliedTags?: readonly Snowflake[]; flags?: ChannelFlagsResolvable; reason?: string; } @@ -6738,7 +6767,7 @@ export interface WebhookMessageCreateOptions extends Omit; } diff --git a/packages/discord.js/typings/index.test-d.ts b/packages/discord.js/typings/index.test-d.ts index b7d9d6222..679c9ad69 100644 --- a/packages/discord.js/typings/index.test-d.ts +++ b/packages/discord.js/typings/index.test-d.ts @@ -193,6 +193,7 @@ import { } from '.'; import { expectAssignable, expectNotAssignable, expectNotType, expectType } from 'tsd'; import type { ContextMenuCommandBuilder, SlashCommandBuilder } from '@discordjs/builders'; +import { ReadonlyCollection } from '@discordjs/collection'; // Test type transformation: declare const serialize: (value: Value) => Serialized; @@ -1171,8 +1172,8 @@ client.on('threadMembersUpdate', (addedMembers, removedMembers, thread) => { expectType>(addedMembers.first()!.client); expectType>(removedMembers.first()!.client); expectType>(thread.client); - expectType>(addedMembers); - expectType>(removedMembers); + expectType>(addedMembers); + expectType>(removedMembers); expectType(thread); const left = removedMembers.first(); if (!left) return; @@ -1990,7 +1991,7 @@ client.on('interactionCreate', async interaction => { const requiredOption = interaction.options.get('name', true); expectType(optionalOption); expectType(requiredOption); - expectType(requiredOption.options); + expectType(requiredOption.options); expectType(interaction.options.getString('name', booleanValue)); expectType(interaction.options.getString('name', false)); @@ -2082,7 +2083,7 @@ collector.on('dispose', (vals, ...other) => { }); collector.on('end', (collection, reason) => { - expectType>(collection); + expectType>(collection); expectType(reason); });