Use async.parallel with Typescript (no callbacks)

11 May 2021

If you landed on this post, chances are you've run into a typescript oddness when using caolan/async's parallel function. The solution to this issue is provided in the type definitions of @types/async — but you'd have to be fairly experienced with typescript to get anything meaningful out of there.

There seems to be no documentation out there regarding this issue which leads me to write this post. I'll explain how I got parallel working without using any callback functions that you'd find in traditional Promise code examples.

import { parallel } from "async";

const one = async () => {
  // do something..
  return true;
};

const two = async () => {
  // do another thing..
  return "meep";
};

const myFunction = async () => {
  // ⭐️ add the 3 arguments here, this is key to making this work
  const result = await parallel<null, [boolean, string], Error>([one, two]);

  return result; // [true, 'meep']
};

When using parallel in an async function, you need to provide it 3 argument types.

  • The first argument we set as null as it's no use to us since we're not using callback functions.
  • The second argument is the array of results. We must tell the parallel function what our expected results are. It doesn't automatically map the expected results for us — like all other cool libraries ☹️.
  • The last argument is the error type we expect when at least one of the async functions fails. Typically the Error type.

Note: The parallel function will fast-fail when a single function errors out (or rejects).

The Better Alternative

Another way of running async functions in parallel is to use Promise.all. It's a built-in feature so 3rd party libraries aren't required — and it has much better typescript support!

const one = async () => {
  // do something..
  return true;
};

const two = async () => {
  // do another thing..
  return "meep";
};

const myFunction = async () => {
  const result = await Promise.all([one(), two()]);

  return result; // [true, 'meep']
};

Using Promise.all results in smaller and much cleaner code. We didn't have to manually specify our expected results, as we did with async.parallel.


Jeff Bocala © 2021. This portfolio site is built with Next.js.
🇦🇺🦘