Reputation: 21000
I have a function that returns a promise which gets some data using fetch:
export function funcWithOptsArgs(a: string, b: number, c?: string): Promise<number> {
// Some API call.
return fetch('/blah/blah').then(() => Promise.resolve(10));
}
I have written a custom hook to manage API calls from my components. It is defined as an overloaded function to accept a callback with variable number of arguments.
export type StreamHook<Data, Callback> = [{ loading: boolean, data: Data | null, error: any }, Callback];
// Custom react hook for API call
export function useAsyncAction<Data>(callback: () => Promise<Data>): StreamHook<Data, () => void>;
export function useAsyncAction<A1, Data>(callback: (a1: A1) => Promise<Data>): StreamHook<Data, (a1: A1) => void>;
export function useAsyncAction<A1, A2, Data>(callback: (a1: A1, a2: A2) => Promise<Data>): StreamHook<Data, (a1: A1, a2: A2) => void>;
export function useAsyncAction<A1, A2, A3, Data>(callback: (a1: A1, a2: A2, a3: A3) => Promise<Data>): StreamHook<Data, (a1: A1, a2: A2, a3: A3) => void>;
export function useAsyncAction<Data>(callback: (...args: any[]) => Promise<Data>): StreamHook<Data, any> {
// TODO: Implementation
return {} as any;
}
When I use it in my component, it works perfectly well except for the optional argument - c
in the above example.
// Usage
function MyComp() {
const [data, doFetch] = useAsyncAction(funcWithOptsArgs);
// Somewhere within the component
// Works perfectly well.
doFetch('Harshal', 32);
// ERROR: Typescript error. Not accepting third argument
doFetch('Harshal', 32, 'Patil');
}
Basically, it interprets doFetch
as doFetch: (a1: string, a2: number) => void
while ignoring the optional argument. I tried many different styles to write the signature but nothing seems to work.
Any solution to make this work?
Upvotes: 2
Views: 45
Reputation: 8340
You can try to use tuple type in rest parameters:
export function useAsyncAction<Args extends readonly unknown[], Data>(callback: (...args: Args) => Promise<Data>): StreamHook<Data, (...args: Args) => void> {
// TODO: Implementation
return {} as any;
}
Upvotes: 1