diff --git a/typings/index.d.ts b/typings/index.d.ts index ce3050d848bc..0ea5497a7dbf 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -150,7 +150,7 @@ declare enum WebhookTypes { 'Channel Follower' = 2, } -type Awaited = T | Promise; +type Awaited = T | PromiseLike; declare module '@discordjs/voice' { import { GatewayVoiceServerUpdateDispatchData, GatewayVoiceStateUpdateDispatchData } from 'discord-api-types/v8'; @@ -1793,13 +1793,16 @@ declare module 'discord.js' { public readonly ids: number[]; public mode: ShardingManagerMode; public parentPort: any | null; - public broadcastEval(fn: (client: Client) => T): Promise; - public broadcastEval(fn: (client: Client) => T, options: { shard: number }): Promise; - public broadcastEval(fn: (client: Client, context: P) => T, options: { context: P }): Promise; + public broadcastEval(fn: (client: Client) => Awaited): Promise[]>; + public broadcastEval(fn: (client: Client) => Awaited, options: { shard: number }): Promise>; public broadcastEval( - fn: (client: Client, context: P) => T, + fn: (client: Client, context: Serialized

) => Awaited, + options: { context: P }, + ): Promise[]>; + public broadcastEval( + fn: (client: Client, context: Serialized

) => Awaited, options: { context: P; shard: number }, - ): Promise; + ): Promise>; public fetchClientValues(prop: string): Promise; public fetchClientValues(prop: string, shard: number): Promise; public respawnAll(options?: MultipleShardRespawnOptions): Promise; @@ -1822,13 +1825,16 @@ declare module 'discord.js' { public totalShards: number | 'auto'; public shardList: number[] | 'auto'; public broadcast(message: any): Promise; - public broadcastEval(fn: (client: Client) => T): Promise; - public broadcastEval(fn: (client: Client) => T, options: { shard: number }): Promise; - public broadcastEval(fn: (client: Client, context: P) => T, options: { context: P }): Promise; + public broadcastEval(fn: (client: Client) => Awaited): Promise[]>; + public broadcastEval(fn: (client: Client) => Awaited, options: { shard: number }): Promise>; + public broadcastEval( + fn: (client: Client, context: Serialized

) => Awaited, + options: { context: P }, + ): Promise[]>; public broadcastEval( - fn: (client: Client, context: P) => T, + fn: (client: Client, context: Serialized

) => Awaited, options: { context: P; shard: number }, - ): Promise; + ): Promise>; public createShard(id: number): Shard; public fetchClientValues(prop: string): Promise; public fetchClientValues(prop: string, shard: number): Promise; @@ -4408,5 +4414,17 @@ declare module 'discord.js' { | 'STAGE_INSTANCE_UPDATE' | 'STAGE_INSTANCE_DELETE'; + type Serialized = T extends symbol | bigint | (() => unknown) + ? never + : T extends number | string | boolean | undefined + ? T + : T extends { toJSON(): infer R } + ? R + : T extends ReadonlyArray + ? Serialized[] + : T extends ReadonlyMap | ReadonlySet + ? {} + : { [K in keyof T]: Serialized }; + //#endregion } diff --git a/typings/index.ts b/typings/index.ts index 788f17adc1be..1934d54f3796 100644 --- a/typings/index.ts +++ b/typings/index.ts @@ -1,6 +1,17 @@ /// -import { Client, Intents, Message, MessageAttachment, MessageEmbed } from 'discord.js'; +import { + Client, + Collection, + Intents, + Message, + MessageAttachment, + MessageEmbed, + Permissions, + Serialized, + ShardClientUtil, + ShardingManager, +} from 'discord.js'; const client: Client = new Client({ intents: Intents.NON_PRIVILEGED, @@ -48,3 +59,42 @@ client.on('message', ({ channel }) => { }); client.login('absolutely-valid-token'); + +// Test type transformation: +declare const assertType: (value: T) => asserts value is T; +declare const serialize: (value: T) => Serialized; + +assertType(serialize(undefined)); +assertType(serialize(null)); +assertType(serialize([1, 2, 3])); +assertType<{}>(serialize(new Set([1, 2, 3]))); +assertType<{}>( + serialize( + new Map([ + [1, '2'], + [2, '4'], + ]), + ), +); +assertType(serialize(new Permissions(Permissions.FLAGS.ATTACH_FILES))); +assertType(serialize(new Intents(Intents.FLAGS.GUILDS))); +assertType( + serialize( + new Collection([ + [1, '2'], + [2, '4'], + ]), + ), +); +assertType(serialize(Symbol('a'))); +assertType(serialize(() => {})); +assertType(serialize(BigInt(42))); + +// Test type return of broadcastEval: +declare const shardClientUtil: ShardClientUtil; +declare const shardingManager: ShardingManager; + +assertType>(shardingManager.broadcastEval(() => 1)); +assertType>(shardClientUtil.broadcastEval(() => 1)); +assertType>(shardingManager.broadcastEval(async () => 1)); +assertType>(shardClientUtil.broadcastEval(async () => 1));