Skip to content

Commit e8d30bc

Browse files
committed
chore: ReadonlyCollection
1 parent ef5d278 commit e8d30bc

File tree

3 files changed

+64
-42
lines changed

3 files changed

+64
-42
lines changed

packages/discord.js/.eslintrc.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,13 +226,25 @@
226226
"selector": "MethodDefinition > TSEmptyBodyFunctionExpression > Identifier :not(TSTypeOperator[operator=readonly]) > TSArrayType",
227227
"message": "Array parameters on methods must be readonly"
228228
},
229+
{
230+
"selector": "MethodDefinition > TSEmptyBodyFunctionExpression > Identifier TSTypeReference > Identifier[name=Collection]",
231+
"message": "Parameters of type Collection on methods must use ReadonlyCollection"
232+
},
229233
{
230234
"selector": "TSDeclareFunction > Identifier :not(TSTypeOperator[operator=readonly]) > TSArrayType",
231235
"message": "Array parameters on functions must be readonly"
232236
},
237+
{
238+
"selector": "TSDeclareFunction Identifier TSTypeReference > Identifier[name=Collection]",
239+
"message": "Parameters of type Collection on functions must use ReadonlyCollection"
240+
},
233241
{
234242
"selector": "TSInterfaceDeclaration TSPropertySignature :not(TSTypeOperator[operator=readonly]) > TSArrayType",
235243
"message": "Array properties on interfaces must be readonly"
244+
},
245+
{
246+
"selector": "TSInterfaceDeclaration TSPropertySignature TSTypeReference > Identifier[name=Collection]",
247+
"message": "Interface properties of type Collection must use ReadonlyCollection"
236248
}
237249
]
238250
}

packages/discord.js/typings/index.d.ts

Lines changed: 47 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -410,11 +410,11 @@ export class AutoModerationRule extends Base {
410410
public setActions(actions: readonly AutoModerationActionOptions[], reason?: string): Promise<AutoModerationRule>;
411411
public setEnabled(enabled?: boolean, reason?: string): Promise<AutoModerationRule>;
412412
public setExemptRoles(
413-
roles: Collection<Snowflake, Role> | readonly RoleResolvable[],
413+
roles: ReadonlyCollection<Snowflake, Role> | readonly RoleResolvable[],
414414
reason?: string,
415415
): Promise<AutoModerationRule>;
416416
public setExemptChannels(
417-
channels: Collection<Snowflake, GuildBasedChannel> | readonly GuildChannelResolvable[],
417+
channels: ReadonlyCollection<Snowflake, GuildBasedChannel> | readonly GuildChannelResolvable[],
418418
reason?: string,
419419
): Promise<AutoModerationRule>;
420420
}
@@ -1113,7 +1113,7 @@ export interface CollectorEventTypes<Key, Value, Extras extends unknown[] = []>
11131113
collect: [Value, ...Extras];
11141114
ignore: [Value, ...Extras];
11151115
dispose: [Value, ...Extras];
1116-
end: [collected: Collection<Key, Value>, reason: string];
1116+
end: [collected: ReadonlyCollection<Key, Value>, reason: string];
11171117
}
11181118

11191119
export abstract class Collector<Key, Value, Extras extends unknown[] = []> extends EventEmitter {
@@ -2268,8 +2268,8 @@ export class MessageFlagsBitField extends BitField<MessageFlagsString> {
22682268
export class MessageMentions<InGuild extends boolean = boolean> {
22692269
private constructor(
22702270
message: Message,
2271-
users: readonly APIUser[] | Collection<Snowflake, User>,
2272-
roles: readonly Snowflake[] | Collection<Snowflake, Role>,
2271+
users: readonly APIUser[] | ReadonlyCollection<Snowflake, User>,
2272+
roles: readonly Snowflake[] | ReadonlyCollection<Snowflake, Role>,
22732273
everyone: boolean,
22742274
repliedUser?: APIUser | User,
22752275
);
@@ -2587,7 +2587,10 @@ export class ReactionCollector extends Collector<Snowflake | string, MessageReac
25872587
event: 'collect' | 'dispose' | 'remove' | 'ignore',
25882588
listener: (reaction: MessageReaction, user: User) => void,
25892589
): this;
2590-
public on(event: 'end', listener: (collected: Collection<Snowflake, MessageReaction>, reason: string) => void): this;
2590+
public on(
2591+
event: 'end',
2592+
listener: (collected: ReadonlyCollection<Snowflake, MessageReaction>, reason: string) => void,
2593+
): this;
25912594
public on(event: string, listener: (...args: readonly any[]) => void): this;
25922595

25932596
public once(
@@ -2596,7 +2599,7 @@ export class ReactionCollector extends Collector<Snowflake | string, MessageReac
25962599
): this;
25972600
public once(
25982601
event: 'end',
2599-
listener: (collected: Collection<Snowflake, MessageReaction>, reason: string) => void,
2602+
listener: (collected: ReadonlyCollection<Snowflake, MessageReaction>, reason: string) => void,
26002603
): this;
26012604
public once(event: string, listener: (...args: readonly any[]) => void): this;
26022605
}
@@ -3318,7 +3321,7 @@ export class UserFlagsBitField extends BitField<UserFlagsString> {
33183321
export function basename(path: string, ext?: string): string;
33193322
export function cleanContent(str: string, channel: TextBasedChannel): string;
33203323
export function discordSort<Key, Value extends { rawPosition: number; id: Snowflake }>(
3321-
collection: Collection<Key, Value>,
3324+
collection: ReadonlyCollection<Key, Value>,
33223325
): Collection<Key, Value>;
33233326
export function cleanCodeBlockContent(text: string): string;
33243327
export function fetchRecommendedShardCount(token: string, options?: FetchRecommendedShardCountOptions): Promise<number>;
@@ -3346,7 +3349,7 @@ export function setPosition<Item extends Channel | Role>(
33463349
item: Item,
33473350
position: number,
33483351
relative: boolean,
3349-
sorted: Collection<Snowflake, Item>,
3352+
sorted: ReadonlyCollection<Snowflake, Item>,
33503353
client: Client<true>,
33513354
route: string,
33523355
reason?: string,
@@ -4187,11 +4190,11 @@ export class GuildEmojiRoleManager extends DataManager<Snowflake, Role, RoleReso
41874190
public emoji: GuildEmoji;
41884191
public guild: Guild;
41894192
public add(
4190-
roleOrRoles: RoleResolvable | readonly RoleResolvable[] | Collection<Snowflake, Role>,
4193+
roleOrRoles: RoleResolvable | readonly RoleResolvable[] | ReadonlyCollection<Snowflake, Role>,
41914194
): Promise<GuildEmoji>;
4192-
public set(roles: readonly RoleResolvable[] | Collection<Snowflake, Role>): Promise<GuildEmoji>;
4195+
public set(roles: readonly RoleResolvable[] | ReadonlyCollection<Snowflake, Role>): Promise<GuildEmoji>;
41934196
public remove(
4194-
roleOrRoles: RoleResolvable | readonly RoleResolvable[] | Collection<Snowflake, Role>,
4197+
roleOrRoles: RoleResolvable | readonly RoleResolvable[] | ReadonlyCollection<Snowflake, Role>,
41954198
): Promise<GuildEmoji>;
41964199
}
41974200

@@ -4302,12 +4305,15 @@ export class GuildMemberRoleManager extends DataManager<Snowflake, Role, RoleRes
43024305
public guild: Guild;
43034306

43044307
public add(
4305-
roleOrRoles: RoleResolvable | readonly RoleResolvable[] | Collection<Snowflake, Role>,
4308+
roleOrRoles: RoleResolvable | readonly RoleResolvable[] | ReadonlyCollection<Snowflake, Role>,
4309+
reason?: string,
4310+
): Promise<GuildMember>;
4311+
public set(
4312+
roles: readonly RoleResolvable[] | ReadonlyCollection<Snowflake, Role>,
43064313
reason?: string,
43074314
): Promise<GuildMember>;
4308-
public set(roles: readonly RoleResolvable[] | Collection<Snowflake, Role>, reason?: string): Promise<GuildMember>;
43094315
public remove(
4310-
roleOrRoles: RoleResolvable | readonly RoleResolvable[] | Collection<Snowflake, Role>,
4316+
roleOrRoles: RoleResolvable | readonly RoleResolvable[] | ReadonlyCollection<Snowflake, Role>,
43114317
reason?: string,
43124318
): Promise<GuildMember>;
43134319
}
@@ -4348,7 +4354,7 @@ export class PermissionOverwriteManager extends CachedManager<
43484354
> {
43494355
private constructor(client: Client<true>, iterable?: Iterable<RawPermissionOverwriteData>);
43504356
public set(
4351-
overwrites: readonly OverwriteResolvable[] | Collection<Snowflake, OverwriteResolvable>,
4357+
overwrites: readonly OverwriteResolvable[] | ReadonlyCollection<Snowflake, OverwriteResolvable>,
43524358
reason?: string,
43534359
): Promise<NonThreadGuildBasedChannel>;
43544360
private upsert(
@@ -4579,7 +4585,7 @@ export interface ActivityOptions {
45794585
export interface AddGuildMemberOptions {
45804586
accessToken: string;
45814587
nick?: string;
4582-
roles?: Collection<Snowflake, Role> | readonly RoleResolvable[];
4588+
roles?: ReadonlyCollection<Snowflake, Role> | readonly RoleResolvable[];
45834589
mute?: boolean;
45844590
deaf?: boolean;
45854591
force?: boolean;
@@ -5021,7 +5027,7 @@ export type CacheWithLimitsOptions = {
50215027

50225028
export interface CategoryCreateChannelOptions {
50235029
name: string;
5024-
permissionOverwrites?: readonly OverwriteResolvable[] | Collection<Snowflake, OverwriteResolvable>;
5030+
permissionOverwrites?: readonly OverwriteResolvable[] | ReadonlyCollection<Snowflake, OverwriteResolvable>;
50255031
topic?: string;
50265032
type?: CategoryChannelType;
50275033
nsfw?: boolean;
@@ -5106,7 +5112,7 @@ export interface ClientEvents {
51065112
guildMemberAvailable: [member: GuildMember | PartialGuildMember];
51075113
guildMemberRemove: [member: GuildMember | PartialGuildMember];
51085114
guildMembersChunk: [
5109-
members: Collection<Snowflake, GuildMember>,
5115+
members: ReadonlyCollection<Snowflake, GuildMember>,
51105116
guild: Guild,
51115117
data: { index: number; count: number; notFound: readonly unknown[]; nonce: string | undefined },
51125118
];
@@ -5118,10 +5124,13 @@ export interface ClientEvents {
51185124
messageDelete: [message: Message | PartialMessage];
51195125
messageReactionRemoveAll: [
51205126
message: Message | PartialMessage,
5121-
reactions: Collection<string | Snowflake, MessageReaction>,
5127+
reactions: ReadonlyCollection<string | Snowflake, MessageReaction>,
51225128
];
51235129
messageReactionRemoveEmoji: [reaction: MessageReaction | PartialMessageReaction];
5124-
messageDeleteBulk: [messages: Collection<Snowflake, Message | PartialMessage>, channel: GuildTextBasedChannel];
5130+
messageDeleteBulk: [
5131+
messages: ReadonlyCollection<Snowflake, Message | PartialMessage>,
5132+
channel: GuildTextBasedChannel,
5133+
];
51255134
messageReactionAdd: [reaction: MessageReaction | PartialMessageReaction, user: User | PartialUser];
51265135
messageReactionRemove: [reaction: MessageReaction | PartialMessageReaction, user: User | PartialUser];
51275136
messageUpdate: [oldMessage: Message | PartialMessage, newMessage: Message | PartialMessage];
@@ -5133,11 +5142,11 @@ export interface ClientEvents {
51335142
roleUpdate: [oldRole: Role, newRole: Role];
51345143
threadCreate: [thread: AnyThreadChannel, newlyCreated: boolean];
51355144
threadDelete: [thread: AnyThreadChannel];
5136-
threadListSync: [threads: Collection<Snowflake, AnyThreadChannel>, guild: Guild];
5145+
threadListSync: [threads: ReadonlyCollection<Snowflake, AnyThreadChannel>, guild: Guild];
51375146
threadMemberUpdate: [oldMember: ThreadMember, newMember: ThreadMember];
51385147
threadMembersUpdate: [
5139-
addedMembers: Collection<Snowflake, ThreadMember>,
5140-
removedMembers: Collection<Snowflake, ThreadMember | PartialThreadMember>,
5148+
addedMembers: ReadonlyCollection<Snowflake, ThreadMember>,
5149+
removedMembers: ReadonlyCollection<Snowflake, ThreadMember | PartialThreadMember>,
51415150
thread: AnyThreadChannel,
51425151
];
51435152
threadUpdate: [oldThread: AnyThreadChannel, newThread: AnyThreadChannel];
@@ -5248,12 +5257,12 @@ export interface CommandInteractionOption<Cached extends CacheType = CacheType>
52485257
}
52495258

52505259
export interface CommandInteractionResolvedData<Cached extends CacheType = CacheType> {
5251-
users?: Collection<Snowflake, User>;
5252-
members?: Collection<Snowflake, CacheTypeReducer<Cached, GuildMember, APIInteractionDataResolvedGuildMember>>;
5253-
roles?: Collection<Snowflake, CacheTypeReducer<Cached, Role, APIRole>>;
5254-
channels?: Collection<Snowflake, CacheTypeReducer<Cached, Channel, APIInteractionDataResolvedChannel>>;
5255-
messages?: Collection<Snowflake, CacheTypeReducer<Cached, Message, APIMessage>>;
5256-
attachments?: Collection<Snowflake, Attachment>;
5260+
users?: ReadonlyCollection<Snowflake, User>;
5261+
members?: ReadonlyCollection<Snowflake, CacheTypeReducer<Cached, GuildMember, APIInteractionDataResolvedGuildMember>>;
5262+
roles?: ReadonlyCollection<Snowflake, CacheTypeReducer<Cached, Role, APIRole>>;
5263+
channels?: ReadonlyCollection<Snowflake, CacheTypeReducer<Cached, Channel, APIInteractionDataResolvedChannel>>;
5264+
messages?: ReadonlyCollection<Snowflake, CacheTypeReducer<Cached, Message, APIMessage>>;
5265+
attachments?: ReadonlyCollection<Snowflake, Attachment>;
52575266
}
52585267

52595268
export interface AutocompleteFocusedOption extends Pick<CommandInteractionOption, 'name'> {
@@ -5502,8 +5511,8 @@ export interface FetchChannelOptions extends BaseFetchOptions {
55025511
}
55035512

55045513
export interface FetchedThreads {
5505-
threads: Collection<Snowflake, AnyThreadChannel>;
5506-
members: Collection<Snowflake, ThreadMember>;
5514+
threads: ReadonlyCollection<Snowflake, AnyThreadChannel>;
5515+
members: ReadonlyCollection<Snowflake, ThreadMember>;
55075516
}
55085517

55095518
export interface FetchedThreadsMore extends FetchedThreads {
@@ -5758,8 +5767,8 @@ export interface AutoModerationRuleCreateOptions {
57585767
triggerMetadata?: AutoModerationTriggerMetadataOptions;
57595768
actions: readonly AutoModerationActionOptions[];
57605769
enabled?: boolean;
5761-
exemptRoles?: Collection<Snowflake, Role> | readonly RoleResolvable[];
5762-
exemptChannels?: Collection<Snowflake, GuildBasedChannel> | readonly GuildChannelResolvable[];
5770+
exemptRoles?: ReadonlyCollection<Snowflake, Role> | readonly RoleResolvable[];
5771+
exemptChannels?: ReadonlyCollection<Snowflake, GuildBasedChannel> | readonly GuildChannelResolvable[];
57635772
reason?: string;
57645773
}
57655774

@@ -5803,7 +5812,7 @@ export interface GuildChannelEditOptions {
58035812
parent?: CategoryChannelResolvable | null;
58045813
rateLimitPerUser?: number;
58055814
lockPermissions?: boolean;
5806-
permissionOverwrites?: readonly OverwriteResolvable[] | Collection<Snowflake, OverwriteResolvable>;
5815+
permissionOverwrites?: readonly OverwriteResolvable[] | ReadonlyCollection<Snowflake, OverwriteResolvable>;
58075816
defaultAutoArchiveDuration?: ThreadAutoArchiveDuration;
58085817
rtcRegion?: string | null;
58095818
videoQualityMode?: VideoQualityMode | null;
@@ -5867,13 +5876,13 @@ export interface GuildEditOptions {
58675876
export interface GuildEmojiCreateOptions {
58685877
attachment: BufferResolvable | Base64Resolvable;
58695878
name: string;
5870-
roles?: Collection<Snowflake, Role> | readonly RoleResolvable[];
5879+
roles?: ReadonlyCollection<Snowflake, Role> | readonly RoleResolvable[];
58715880
reason?: string;
58725881
}
58735882

58745883
export interface GuildEmojiEditOptions {
58755884
name?: string;
5876-
roles?: Collection<Snowflake, Role> | readonly RoleResolvable[];
5885+
roles?: ReadonlyCollection<Snowflake, Role> | readonly RoleResolvable[];
58775886
reason?: string;
58785887
}
58795888

@@ -5894,7 +5903,7 @@ export interface GuildStickerEditOptions {
58945903

58955904
export interface GuildMemberEditOptions {
58965905
nick?: string | null;
5897-
roles?: Collection<Snowflake, Role> | readonly RoleResolvable[];
5906+
roles?: ReadonlyCollection<Snowflake, Role> | readonly RoleResolvable[];
58985907
mute?: boolean;
58995908
deaf?: boolean;
59005909
channel?: GuildVoiceChannelResolvable | null;

packages/discord.js/typings/index.test-d.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ import {
193193
} from '.';
194194
import { expectAssignable, expectNotAssignable, expectNotType, expectType } from 'tsd';
195195
import type { ContextMenuCommandBuilder, SlashCommandBuilder } from '@discordjs/builders';
196+
import { ReadonlyCollection } from '@discordjs/collection';
196197

197198
// Test type transformation:
198199
declare const serialize: <Value>(value: Value) => Serialized<Value>;
@@ -1171,8 +1172,8 @@ client.on('threadMembersUpdate', (addedMembers, removedMembers, thread) => {
11711172
expectType<Client<true>>(addedMembers.first()!.client);
11721173
expectType<Client<true>>(removedMembers.first()!.client);
11731174
expectType<Client<true>>(thread.client);
1174-
expectType<Collection<Snowflake, ThreadMember>>(addedMembers);
1175-
expectType<Collection<Snowflake, ThreadMember | PartialThreadMember>>(removedMembers);
1175+
expectType<ReadonlyCollection<Snowflake, ThreadMember>>(addedMembers);
1176+
expectType<ReadonlyCollection<Snowflake, ThreadMember | PartialThreadMember>>(removedMembers);
11761177
expectType<AnyThreadChannel>(thread);
11771178
const left = removedMembers.first();
11781179
if (!left) return;
@@ -1990,7 +1991,7 @@ client.on('interactionCreate', async interaction => {
19901991
const requiredOption = interaction.options.get('name', true);
19911992
expectType<CommandInteractionOption | null>(optionalOption);
19921993
expectType<CommandInteractionOption>(requiredOption);
1993-
expectType<CommandInteractionOption[] | undefined>(requiredOption.options);
1994+
expectType<readonly CommandInteractionOption[] | undefined>(requiredOption.options);
19941995

19951996
expectType<string | null>(interaction.options.getString('name', booleanValue));
19961997
expectType<string | null>(interaction.options.getString('name', false));
@@ -2082,7 +2083,7 @@ collector.on('dispose', (vals, ...other) => {
20822083
});
20832084

20842085
collector.on('end', (collection, reason) => {
2085-
expectType<Collection<string, Interaction>>(collection);
2086+
expectType<ReadonlyCollection<string, Interaction>>(collection);
20862087
expectType<string>(reason);
20872088
});
20882089

0 commit comments

Comments
 (0)