I face this problem when I try to setup an interface to the state when trying to use useReducer.I use it in a custom hook for fetching data from the server. The data object in response from the server may contain different properties. the useFetcher.ts
const initialState = {
data: null,
loading: false,
error: null,
};
type LIST_RESPONSE = {
page: number;
totalRows: number;
pageSize: number;
totalPages: number;
list: [];
};
interface State {
data: LIST_RESPONSE| null;
loading: boolean;
error: string | null;
}
const reducer = (state: State, action: ACTIONTYPES) => {
switch (action.type) {
case ACTIONS.FETCHING: {
return {
...state,
loading: true,
};
}
case ACTIONS.FETCH_SUCCESS: {
return {
...state,
loading: false,
data: action.data,
};
}
case ACTIONS.ERROR: {
return {
...state,
loading: false,
error: action.error,
};
}
}
};
const useFetcher = (url: string): State => {
const [state, dispatch] = useReducer(reducer, initialState);
const { data, loading, error } = state;
useEffect(() => {
dispatch({ type: ACTIONS.FETCHING });
const fetchData = async () => {
try {
const response = await httpService.get(url);
dispatch({ type: ACTIONS.FETCH_SUCCESS, data: response.data });
return;
} catch (error: unknown) {
const { message } = error as Error;
dispatch({ type: ACTIONS.ERROR, error: message });
}
};
fetchData();
}, [url]);
return { data, loading, error };
};
export default useFetcher;
Component A call useFetcher:
const { data, loading, error } = useFetcher('productList');
this works fine, it returns the data object that fits the LIST_RESPONSE type. but if I want want to use the useFetcher function in Component B, it is expected to return another data type, let's say like this:
type CATEGORTY_RESPONSE= {
categories: [];
};
How can I make the data type in the interface State generic? for example, I can define the data type in the State interface when I am calling the useFecher hook like this: component A:
const { data, loading, error } = useFetcher<LIST_RESPONSE>('productList');
component B:
const { data, loading, error } = useFetcher<CATEGORTY_RESPONSE>('categories');
I tried
interface State {
data: LIST_RESPONSE|CATEGORTY_RESPONSE| null;
loading: boolean;
error: string | null;
}
or
const useFetcher = <Type extends State>(url: string): Type =>{...}
none of them works. Any help?thanks