I've been looking at different resources online trying to find a working solution for what I have and so far I think I'm kinda botching my typescript integration. I'd love to have some help in properly setting up my types for my hook.
I have a useUser() hook that dispatches actions to my reducer and also returns selectors back from my store. I've made some progress, but I'm starting to get in over my head a little bit.
the hook: useUser.ts
- I'm not sure what I can place as the return for this hook. I tried placing
useUserActionTypesbut I don't think that makes any difference, especially since I'm not returning anything really beyond either getting an object (userData), or a number (totalPoints,totalWords) from the store. - I dont think I should be "returning" my dispatches, but it made typescript less upset
- I can also just type in something like 'Dog' instead of
FETCH_USERinto my dispatch's type for example. Probably doesn't matter, but I think there should be a safeguard in there, right? - Pretty stumped with how to actually fix that error in the destructured return. I have a type called
Userthat represents an object that my store will have for user, but ... that made no difference.
import { useSelector, useDispatch } from 'react-redux';
import axios from 'axios';
import { User } from '../reducers/user';
export const FETCH_USER = 'FETCH_USER';
export const UPDATE_ERRORS = 'UPDATE_ERRORS';
export const INCREMENT_POINTS = 'INCREMENT_POINTS';
export const INCREMENT_WORDS = 'INCREMENT_WORDS';
type Error = {
code: number;
message: string;
};
type FetchUserAction = {
type: typeof FETCH_USER;
payload: User;
};
type UpdateErrorsAction = {
type: typeof UPDATE_ERRORS;
payload: Error[];
};
type IncrementPointsAction = {
type: typeof INCREMENT_POINTS;
payload: number;
};
type IncrementWordsActions = {
type: typeof INCREMENT_WORDS;
};
// ? Typescript is able to infer the correct type in the Union Type below
export type useUserActionTypes =
| FetchUserAction
| UpdateErrorsAction
| IncrementPointsAction
| IncrementWordsActions;
export type ReduxStore = {
alert: any;
user: User;
};
const useUser = (): useUserActionTypes => {
const userData: User = useSelector((state: ReduxStore) => state.user);
const totalPoints: number = useSelector(
(state: ReduxStore) => state.user.points
);
const totalWords: number = useSelector(
(state: ReduxStore) => state.user.words
);
const dispatch = useDispatch();
const fetchUser = async (): Promise<FetchUserAction | UpdateErrorsAction> => {
try {
const response = await axios.get(
'http://localhost:5000/api/v1/users/WhpHq4qWFdzlhlx2ztqD'
);
const user = response.data;
return dispatch({
type: FETCH_USER,
payload: user,
});
} catch (error) {
return dispatch({
type: UPDATE_ERRORS,
payload: [
{
code: 500,
message: error.message,
},
],
});
}
};
const incrementPoints = (amount: number): useUserActionTypes => {
return dispatch({
type: INCREMENT_POINTS,
payload: amount,
});
};
const incrementWords = (): useUserActionTypes => {
return dispatch({
type: INCREMENT_WORDS,
});
};
return {
userData,
totalPoints,
totalWords,
fetchUser,
incrementPoints,
incrementWords,
};
};
export default useUser;
On a page where I am trying to use the selectors:
- I thought these were covered in my hook, I have types assigned to these constants.
fetchUser()returns a type of 'any' ... same issue as above perhaps?
Thank you for any help, It's definitely fun trying to get this all properly hooked up with typescript but I am a bit lost currently.


