Provide Task type for async queue using generics
Asked Answered
T

1

6

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.

Trivandrum answered 25/6, 2018 at 21:51 Comment(4)
Does @types/async exists for async.js? If it exists, you can install npm install @types/asyncTinct
yes of course @types/async exists, but given that, I am looking for how to get the right generic arg for this if possible.Trivandrum
Saw you marked as answered, if the answer was useful, don't forget to assign the bounty as well :)Stradivari
You got it, thanks very muchTrivandrum
S
4

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
Stradivari answered 9/7, 2018 at 12:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.