I want the useFetch
hook to accept any kind of array to be used as the type of data
:
hooks/useFetch.ts:
const useFetch = <T extends any[]>(dataUrl: string) => {
const [data, setData] = useState<T>([]);
const [error, setError] = useState<string | null>(null);
const result = await axios(dataUrl);
setData(result.data);
}
Note: result
is of type AxiosResponse<any, any>
, and the successful result.data
should be an object array. This is the full code of the hook.
App.tsx:
interface City {
rank: number;
city: string;
state: string;
population: string;
}
const { data: cities, error } = useFetch<City[]>('/data.json');
I’m getting the following error on this line const [data, setData] = useState<T>([]);
:
Argument of type ‘never[]’ is not assignable to parameter of type ‘T | (() => T)’.
How to remove this error?
2
Answers
TypeScript doesn’t know what type the empty array is, and so it is assigned to
never[]
by default. Casting the array toT
viauseState<T>([] as T)
will also give you issues due to the same issue you’re currently running into. Unless you explicitly need your generic to extend an array, you can simplify youruseFetch
declaration to:If you had tried casting the
useState()
parameter toT
, you would have seen an error likeThe super simple version is to tell Typescript you know what you’re doing and to shut up with the following…
Another approach you might want to try is creating an array-specific version of your hook, eg
useFetchArray
.With the consumer using
This avoids any ambiguity around generic array types.