Reputation: 92120
I'd like to design a library that wraps any async function. The wrapped async function can have multiple args
If I do
type AsyncFunction<I, O> = (inputs: I) => Promise<O>;
function wrapper<I, O>(
asyncFunction: AsyncFunction<I, O>,
): AsyncFunction<I, O> { ... }
The typing of T will only apply to the first arg so this makes my wrapper unusable with any async function that takes multiple parameters.
Can someone give me a solution to support multiple args?
Edit
This is where I am currently:
type AsyncFunction<I extends any[], O> = (...inputs: I) => Promise<O>;
export function onlyResolvesLast<I extends any[], O>(
asyncFunction: AsyncFunction<I, O>,
): AsyncFunction<I, O> {
let cancelPrevious;
return function wrappedAsyncFunction(...args) {
cancelPrevious && cancelPrevious();
const initialPromise = asyncFunction(...args);
const { promise, cancel } = createImperativePromise(initialPromise);
cancelPrevious = cancel;
return promise;
};
}
Upvotes: 0
Views: 234
Reputation: 92120
I have found the solution I was looking for in existing typedefs:
// Type definitions for debounce-promise 3.1
// Project: https://github.com/bjoerge/debounce-promise
// Definitions by: Wu Haotian <https://github.com/whtsky>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 3.0
declare namespace debounce {
interface DebounceOptions {
leading?: boolean;
accumulate?: boolean;
}
}
type ArgumentsType<T> = T extends (...args: infer A) => any ? A : never;
declare function debounce<T extends (...args: any[]) => any>(
func: T,
wait?: number,
options?: debounce.DebounceOptions
): (
...args: ArgumentsType<T>
) => ReturnType<T> extends Promise<any>
? ReturnType<T>
: Promise<ReturnType<T>>;
export = debounce;
Upvotes: 0
Reputation: 249506
If you want to support multiple parameters you need to use tuples in rest parameters:
type AsyncFunction<I extends any[], O> = (...inputs: I) => Promise<O>;
function wrapper<I extends any[], O>(
asyncFunction: AsyncFunction<I, O>,
): AsyncFunction<I, O> { return asyncFunction }
async function fn(a: number, b: number) {
return 1;
}
wrapper(fn)(1, 2)
Upvotes: 2