Reputation: 1999
I'm learning Typescript and I'm creating a custom React hook to fetch data from the api:
import { useState, useEffect } from 'react';
import api from '../services/api';
interface RequestProps {
url: string;
initialLoading: boolean;
}
interface ResponseProps<T> {
data: T,
error: boolean,
loading: boolean
}
export const useApiRequest = <T>({ url, initialLoading }: RequestProps): ResponseProps<T> => {
// Response state
const [data, setData] = useState<T>();
const [error, setError] = useState(false);
const [loading, setLoading] = useState(initialLoading);
useEffect(() => {
const fetchApi = async () => {
try {
setLoading(true);
// Fetch data from REST API
const response = await api.get<T>(url);
setLoading(false);
setData(response.data);
} catch (e) {
setError(true);
}
};
// Call async function
fetchApi();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [url]);
return {
data,
loading,
error,
};
};
What I'm trying to do is to receive the T
interface as a parameter and assign it to data
, since the data
will be different, according to the API response from different url
. So whenever I call this hook, I want to pass a custom interface for data
, like:
const {data, loading, error} = useApiRequest<MyCustomInterfaceForData>({url: 'https://apiurl', initialLoading: true})
The problem is that Typescript is giving me an error in the data
from the return statement:
TS2322: Type 'T | undefined' is not assignable to type 'T'. 'T' could be instantiated with an arbitrary type which could be unrelated to 'T | undefined'. Type 'undefined' is not assignable to type 'T'. 'T' could be instantiated with an arbitrary type which could be unrelated to 'undefined'. useApiRequest.ts(10, 5): The expected type comes from property 'data' which is declared here on type 'ResponseProps'
What am I missing?
Thanks in advance!
Upvotes: 1
Views: 209
Reputation: 10662
The error says it all, data
can be undefined until response.data
is used for updating the state(data
).
So, try changing the type of response like this:
interface ResponseProps<T> {
data: T | undefined,
error: boolean,
loading: boolean
}
Upvotes: 1