3

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?

1 Answer 1

5

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

Sign up to request clarification or add additional context in comments.

1 Comment

While this works for simple functions I'm afraid it doesn't seem to work for functions with multiple declarations (overloaded functions). Not that it invalidates this answer, just worth noting for someone coming here later.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.