Search code examples
typescriptasync.jstsc

Provide Task type for async queue using generics


I have this right now:

export type EVCb = (err:any, val?:any) => void;
export type Task = (cb: EVCb) => void;
export const q = async.queue((task: Task, cb) => task(cb), 2);

Isn't there a way to give async.queue type information about the task using generics?

something like this:

export const q = async.queue<Task>((task: Task, cb) => task(cb), 2);

I can't figure out if this is the right way to do it or what the right syntax is.


Solution

  • The type definitions for async require 2-3 type arguments. In the version with 2 arguments, the first argument is the task type, and the second argument is the callback. My guess is that these type definitions were written before conditional type were available to extract the callback type from the task (or that the maintainers don't wish to use conditional types to maintain compatibility with versions lower then 2.8).

    You can pass in the second parameter:

    export const q2 = async.queue<Task, EVCb>((task, cb) => task(cb), 2);
    

    Edit

    We can also add a new async method as a module augmentation, that only requires one parameter, as since typescript 2.8 it is now possible to extract type parameters from other types (this could be a good contribution to the definitions if anyone is willing to do it):

    declare module 'async' {
        type GetCallbackParameter<T extends (cb: any)=> void> = T extends (cb: infer C)=> void ? C: never;
    
        export function queue<T extends (cb: any)=> void>(worker: async.AsyncWorker<T,GetCallbackParameter<T>> , concurrency?: number): AsyncQueue<T>;
    }
    
    export const q2 = async.queue<Task>((task, cb) => task(cb), 2); // cb inferred correctly