Home > Blockchain >  How do you create an async version of a TypeScript function type?
How do you create an async version of a TypeScript function type?

Time:07-09

I have a non-async function type in TypeScript and I want the same function type but async.

// this is a function type
type MyFunction = (x: number) => void;
// this is an async version of the same function type, created explicitly
type AsyncMyFunction = (x: number) => Promise<void>;

MyFunction could be any function, so more generically it's (...args: any[]) => any.

// how do I get the async version generically without knowing the actual function type?
type AsyncWrapper<T> = (/*args of T*/) => Promise</*return type of T*/>

If it works correctly, I should be able to use AsyncWrapper<MyFunction> in place of AsyncMyFunction because the AsyncWrapper will be able to copy the parameter types of T and wrap the return type of T in a Promise.

Is this possible?

CodePudding user response:

Here is a simple solution using the utility types Parameters and ReturnType.

type AsyncWrapper<T extends (...args: any) => any> = 
  (...args: Parameters<T>) => Promise<ReturnType<T>>

Playground


Side note: Nested Promises are always flattened in JavaScript. So nested Promise-Types also don't make much sense in TypeScript. If you may also pass functions that already return a Promise to this generic type, you may want to keep their return type as is.

type AsyncWrapper<T extends (...args: any) => any> = 
  (...args: Parameters<T>) => ReturnType<T> extends infer U extends Promise<any> 
    ? U 
    : Promise<ReturnType<T>>

Playground

  • Related