How can I type this function in relation to its input fn?
function makeAsync(fn) {
return async (...args) => fn(...args);
}
It returns a function identical to its input, but instead of returning Type it would return Promise<Type>
Usage example:
const a = () => 1; // Type () => number;
const b = makeAsync(a); // Type () => Promise<number>;
const c = makeAsync(b); // Type () => Promise<number>; // ✅, not Promise<Promise<number>>
This works, but it's a little verbose
// Unwraps a Promise<T> value into just T, so we never get Promise<Promise<T>>
type Unpromise<MaybePromise> = MaybePromise extends Promise<infer Type> ? Type : MaybePromise;
// Like ReturnType, except it returns the unwrapped promise also for async functions
type AsyncReturnType<T extends (...args: any[]) => any> = Unpromise<ReturnType<T>>
// For a `() => T` function it returns its async equivalent `() => Promise<T>`
type PromisedFunction<T extends (...args: any[]) => any> =
(...args: Parameters<T>) => Promise<AsyncReturnType<T>>;
function makeAsync<T extends (...args: any[]) => any>(fn: T): PromisedFunction<T> {
return async (...args) => fn(...args);
}
Are there any better/shorter ways to achieve this?
… => Tand… => Promise<T>work?Promise<Promise<T>>so in the future a solution could be simpler: github.com/microsoft/TypeScript/issues/27711