Home > Enterprise >  Typescript - Typing serialize promises function
Typescript - Typing serialize promises function

Time:11-29

I'm trying to write a wrapper for arbitrary promise-returning functions that makes any call wait for the previous ones to finish.

The JavaScript implementation is below but I'm struggle to write the types for the typescript implementation. How can I type the fn parameter as a generic promise returning function?

function serializePromises(fn) {
  // This works as our promise queue
  let last = Promise.resolve();
  return function (...args) {
    // Catch is necessary here — otherwise a rejection in a promise will
    // break the serializer forever
    last = last.catch(() => {}).then(() => fn(...args));
    return last;
  }
}

CodePudding user response:

The following will work nicely but you may notice a couple casts as it is not possible to accurately type let last = Promise.resolve() due to it resolving without a value initially.

function serializePromises<TArgs extends Array<unknown>, TReturn extends Promise<unknown>>(fn: (...args: TArgs) => TReturn): (...args: TArgs) => TReturn {
  // This works as our promise queue
  let last: Promise<any> = Promise.resolve();
  return function (...args: TArgs) {
    // Catch is necessary here — otherwise a rejection in a promise will
    // break the serializer forever
    last = last.catch(() => {}).then(() => fn(...args));
    return last as TReturn;
  }
}

CodePudding user response:

You can use two generic type params on your function, like this

function serializePromises<Args extends unknown[], R extends unknown>(fn: (...args: Args) => Promise<R>) {
  // This works as our promise queue
  let last = Promise.resolve<null | R>(null);
  
  return function (...args: Args) {
    // Catch is necessary here — otherwise a rejection in a promise will
    // break the serializer forever
    last = last.catch(() => null).then(() => fn(...args));
    return last;
  }
}

Returning null instead of just leting it be undefined is just a recomendation of mine.

Here's a working playground

  • Related