From f2495e5ee9ecdb26492da510dc38730718cb28c5 Mon Sep 17 00:00:00 2001 From: Manuel Astudillo Date: Thu, 14 Nov 2024 16:14:23 +0100 Subject: [PATCH] fix(queue): fix generics to be able to properly be extended --- src/classes/queue.ts | 92 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 72 insertions(+), 20 deletions(-) diff --git a/src/classes/queue.ts b/src/classes/queue.ts index 84cfbcacaf..6601784cdf 100644 --- a/src/classes/queue.ts +++ b/src/classes/queue.ts @@ -29,7 +29,7 @@ export interface ObliterateOpts { count?: number; } -export interface QueueListener +export interface QueueListener extends IoredisListener { /** * Listen to 'cleaned' event. @@ -57,17 +57,14 @@ export interface QueueListener * * This event is triggered when the job updates its progress. */ - progress: ( - job: Job, - progress: number | object, - ) => void; + progress: (job: JobBase, progress: number | object) => void; /** * Listen to 'removed' event. * * This event is triggered when a job is removed. */ - removed: (job: Job) => void; + removed: (job: JobBase) => void; /** * Listen to 'resumed' event. @@ -81,21 +78,74 @@ export interface QueueListener * * This event is triggered when the queue creates a new job. */ - waiting: (job: Job) => void; + waiting: (job: JobBase) => void; } +// Helper for JobBase type +type JobBase = T extends Job< + any, + any, + any +> + ? T + : Job; + +// Helper types to extract DataType, ResultType, and NameType +type ExtractDataType = DataTypeOrJob extends Job< + infer D, + any, + any +> + ? D + : Default; + +type ExtractResultType = DataTypeOrJob extends Job< + any, + infer R, + any +> + ? R + : Default; + +type ExtractNameType< + DataTypeOrJob, + Default extends string, +> = DataTypeOrJob extends Job ? N : Default; + /** * Queue * * This class provides methods to add jobs to a queue and some other high-level * administration such as pausing or deleting queues. * + * @template DataType - The type of the data that the job will process. + * @template ResultType - The type of the result of the job. + * @template NameType - The type of the name of the job. + * + * @example + * + * ```typescript + * import { Queue } from 'bullmq'; + * + * interface MyDataType { + * foo: string; + * } + * + * interface MyResultType { + * bar: string; + * } + * + * const queue = new Queue('myQueue'); + * ``` */ export class Queue< - DataType = any, - ResultType = any, - NameType extends string = string, -> extends QueueGetters> { + DataTypeOrJob = any, + DefaultResultType = any, + DefaultNameType extends string = string, + DataType = ExtractDataType, + ResultType = ExtractResultType, + NameType extends string = ExtractNameType, +> extends QueueGetters> { token = v4(); jobsOpts: BaseJobOptions; opts: QueueOptions; @@ -132,32 +182,34 @@ export class Queue< }); } - emit>( + emit>>( event: U, - ...args: Parameters[U]> + ...args: Parameters< + QueueListener>[U] + > ): boolean { return super.emit(event, ...args); } - off>( + off>>( eventName: U, - listener: QueueListener[U], + listener: QueueListener>[U], ): this { super.off(eventName, listener); return this; } - on>( + on>>( event: U, - listener: QueueListener[U], + listener: QueueListener>[U], ): this { super.on(event, listener); return this; } - once>( + once>>( event: U, - listener: QueueListener[U], + listener: QueueListener>[U], ): this { super.once(event, listener); return this; @@ -290,7 +342,7 @@ export class Queue< jobId, }, ); - this.emit('waiting', job); + this.emit('waiting', job as JobBase); span?.setAttributes({ [TelemetryAttributes.JobId]: job.id,