import { useCallback, useReducer } from "react";
const ARTIST_REDUCER_TYPES = {
ADD: "ADD",
};
const artistArray = [...Object.values(ARTIST_REDUCER_TYPES)] as const;
type ActionReturnedTypes = (typeof artistArray)[number];
type ReducerStateType = {
artist: { name: string };
albums: { name: string, released: number }[];
topTracks: { name: string released: number }[];
};
type ReducerAction = {
type: ActionReturnedTypes;
payload: ReducerStateType;
};
const artistInitState = {
artist: { name: ""},
albums: [{name: "", released: 0}],
topTracks: [{name: "", released: 0}],
};
export const useArtistResults = (initialState: typeof artistInitState) => {
const [artistDetails, dispatch] = useReducer(
(state: ReducerStateType, action: ReducerAction): ReducerStateType => {
switch (action.type) {
case ARTIST_REDUCER_TYPES.ADD: {
if (!action.payload) {
throw new Error("ADD action requires a payload");
}
return {
...state,
artist: action.payload.artist,
albums: action.payload.albums,
topTracks: action.payload.topTracks,
};
}
}
},
artistInitState
);
const setProfile = useCallback(
(artist, albums, topTracks) => {
dispatch({
type: "ADD",
payload: {
artist,
albums,
topTracks,
},
});
},
[]
);
This is constantly returning this error:
No overload matches this call.
If I take off the type for the state parameter the error goes away. I just don’t seem to know what is causing this. Does this have something to do with the state object not matching the initial state?
I’m so confused
2
Answers
This was an issue with the actual type for the state being slightly incorrect with the initial state.
My above code was an attempt at making it as reproducible as possible. In reality, my code and state is a lot larger than the example I put above so it wasn't a good example
All I had to do was fix the initialState
There were a few mistakes in there so it didn't match the ReducerStateType
Try removing the explicit
ReducerStateType
return type from the reducer function and adding a const assertion toARTIST_REDUCER_TYPES
:This changes the type of that value from:
to:
This allows TypeScript to know that the
switch
inside your reducer is exhaustive.