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>>
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>>