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.