I am using SWR in a React.js application and I find myself needing to display the loading status of a request.
I created a helper function that extracts the loading status from an SWRResponse
similar to what SWR provides in their documentation examples:
const isLoading = ({ data, error }: SWRResponse<any, any>): boolean => {
return data === undefined && error === undefined;
}
I would like to create a wrapper hook, that always adds this information in the return value, similar to the following:
const useSWRWithLoading: SWRHook = (...args) => {
const swrResponse = useSWR(...args);
return { ...swrResponse, isLoading: isLoading(swrResponse) };
};
Since I used the builtin type SWRHook
I have no support for the isLoading
value.
How I tried solving the issue (without any success):
const useSWRWithLoading = (...args: Parameters<SWRHook>): ReturnType<SWRHook> & { isLoading: boolean } => {
const swrResponse = useSWR(...args);
return { ...swrResponse, isLoading: isLoading(swrResponse) };
};
or (this is pretty much the same thing as before)
type SWRHookWithLoading = (...args: Parameters<SWRHook>) => ReturnType<SWRHook> & { isLoading: boolean };
const useSWRWithLoading: SWRHookWithLoading = (...args) => {
const swrResponse = useSWR(...args);
return { ...swrResponse, isLoading: isLoading(swrResponse) };
};
One thing I noticed is that:
type Foo = Parameters<SWRHook>; // type Foo = never
type Bar = ReturnType<SWRHook>; // type Bar = SWRResponse<unknown,unknown>
And I don't know how to fix it.
If I try to make the SWRHookWithLoading
Type a generic, I get an error that says: Type 'SWRHook' is not generic.
.
type SWRHookWithLoading<Data = any, Error = any> = (...args: Parameters<SWRHook<Data, Error>>) => ReturnType<SWRHook<Data, Error>> & { isLoading: boolean };
This is puzzling for me because the type definition for SWRHook
is:
export declare type SWRHook = <Data = any, Error = any>(...args: readonly [Key] | readonly [Key, Fetcher<Data> | null] | readonly [Key, SWRConfiguration<Data, Error> | undefined] | readonly [Key, Fetcher<Data> | null, SWRConfiguration<Data, Error> | undefined]) => SWRResponse<Data, Error>;
which looks like a generic for me.