What I am trying to do?
I want to create a function that can make any type of API request for a frontend application. Basically, I want to get fancy.
Problem?
I am in over my head and I need another eye to take a look at my broken approach.
Here is the error I get from the code below:
Type '<T>(options: TApiHookOptions) => { data: Accessor<T | null>; error: Accessor<Error | null>; loading: Accessor<boolean>; request: void; }' is not assignable to type 'IUseApiHook'.
Call signature return types '{ data: Accessor<unknown>; error: Accessor<Error | null>; loading: Accessor<boolean>; request: void; }' and 'TApiHook<T>' are incompatible.
The types of 'data' are incompatible between these types.
Type 'Accessor<unknown>' is not assignable to type 'T'.
'T' could be instantiated with an arbitrary type which could be unrelated to 'Accessor<unknown>'.ts(2322)
Code (everything is here):
import { createEffect, createSignal } from "solid-js";
import axios from "axios";
export type TApiResponse<T> = {
data: T;
error: Error | null;
};
export type TApiHook<T> = {
data: T | null;
error: Error | null;
loading: boolean;
request: () => void;
};
export type TApiHookOptions = {
url: string;
method?: "get" | "post" | "put" | "delete";
data?: any;
};
export interface IUseApiHook {
<T>(options: TApiHookOptions): TApiHook<T>;
}
export const useApiHook: IUseApiHook = <T>(options: TApiHookOptions) => {
const [data, setData] = createSignal<T | null>(null);
const [error, setError] = createSignal<Error | null>(null);
const [loading, setLoading] = createSignal(false);
const request = createEffect(() => {
setLoading(true);
axios({
url: options.url,
method: options.method || "get",
data: options.data,
})
.then((response) => {
setData(response.data);
setError(null);
})
.catch((error) => {
setError(error);
})
.finally(() => {
setLoading(false);
});
});
return {
data,
error,
loading,
request,
};
};