I try to create a type that takes a function type, wraps the function parameters in Promise<> and returns a new type - the same function but with parameters as Promise, for example:
type PromisedFn = PromisedArgs<(a: number, b: string | number) => void>
// should produce (a: Promise<number>, b: Promise<string | number>) => void
After hours of racking my brains I only managed to achieve such code:
type Func = (id: number, guid: number | string) => number | string;
type FuncParams = Parameters<Func>;
// FuncParams = [id: string, guid: string | number]
type FuncWrappedParams = {
[K in keyof FuncParams as Extract<K, '0'|'1'>]: Promise<FuncParams[K]>
}
// { 0: Promise<number>, 1: Promise<string | number> }
Still number-indexed object can't be applied as an array properly:
type FuncWrappedParamsArray = [...args: FuncWrappedParams[]];
type WrappedParamsFunc = (...args: FuncWrappedParamsArray) => ReturnType<Func>;
let func: WrappedParamsFunc = (
id: Promise<number>,
guid: Promise<number | string>
) => 'TestString';
// ERROR:
// Type '(id: Promise<number>, guid: Promise<number | string>) => string'
// is not assignable to type 'WrappedParamsFunc'.
// Types of parameters 'id' and 'args' are incompatible.
// Type 'FuncWrappedParams' is missing the following properties from type 'Promise<number>':
// then, catch, [Symbol.toStringTag]
I have no idea how to handle this one.
Problem #1 is as above.
Problem #2: the disadvantage is that we must know a number of function parameters ahead of time: [K in keyof FuncParams as Extract<K, '0'|'1'>].