0

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?

enter image description here

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

enter image description here

2 Answers 2

2

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)
Sign up to request clarification or add additional context in comments.

3 Comments

thanks. I've edited my question a bit because I still have an error, can you help? Also it seems like the wrapped function can be called with a single param while the original function takes 2, is this normal?
What version of TypeScript do you use? v3.3 compiles well
you are right @AchmedzhanovNail with 3.3 it works fine, I didn't double check that TS version. However it seems I can still call the fn with 1 param and compilation does not fail
0

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;

Comments

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.