Reducer in the store is showing an error (react, redux toolkit, typescript)

Viewed 20

I am using redux in typescript, i want to make a reducer that will update the state of the store, and my types are:

interface IArticle {
  id: number,
  title: string,
  body: string,
}


type ArticleState = {
  articles: IArticle[]
}


type ArticleAction = {
  type: string, 
  article: IArticle
}

type DispatchType = (args: ArticleAction) => ArticleAction

my actionCreators.ts is like this:

import * as actionTypes from "./actionTypes"

// A function to add an article
export function addArticle(article:IArticle)
{
  const action: ArticleAction={
    type: actionTypes.ADD_ARTICLE,
    article,
  }
  return simulateHttpRequest(action)
}

// A function to remove an article
export function removeArticle(article:IArticle){
  const action: ArticleAction={
    type: actionTypes.REMOVE_ARTICLE,
    article,
  }
  return simulateHttpRequest(action)
}

export function simulateHttpRequest(action: ArticleAction) {
  return (dispatch: DispatchType) => {
    setTimeout(() => {
      dispatch(action)
    }, 500)
  }
}

while my reducer is as follows:

import * as actionTypes from "./actionTypes"

const initialState: ArticleState = {
  articles:[]
}
let lastID =0
const reducer = (state:ArticleState=initialState,action:ArticleAction)=>{
  switch(action.type){
    case actionTypes.ADD_ARTICLE:
      const newArticle:IArticle = {
        id: ++lastID,
        title: action.article.title,
        body: action.article.body
      }
      return { ...state,newArticle}
    
    case actionTypes.REMOVE_ARTICLE:
      return state.articles.filter((article)=> article.id !== action.article.id)
    default: return state
  }
}

export default reducer

so far everything is okay. Finally,my reducer is showing an error when i am trying to make a store as follows:

export const store = configureStore({
  reducer: {
    reducer: reducer,
  }
});

the error:

Type '(state: ArticleState | undefined, action: ArticleAction) => ArticleState | IArticle[] | { newArticle: IArticle; articles: IArticle[]; }' is not assignable to type 'Reducer<ArticleState | IArticle[] | { newArticle: IArticle; articles: IArticle[]; }, AnyAction>'.
  Types of parameters 'state' and 'state' are incompatible.
    Type 'ArticleState | IArticle[] | { newArticle: IArticle; articles: IArticle[]; } | undefined' is not assignable to type 'ArticleState | undefined'.
      Property 'articles' is missing in type 'IArticle[]' but required in type 'ArticleState'.ts(2322)
type.d.ts(10, 3): 'articles' is declared here.

Any help will be appreciated

2 Answers

I think it's complaining about this line

return { ...state, newArticle}

You're overwriting the array of articles with a single article. You should add the new item to the existing array and merge that into the state. Here's one way you could do it:

case actionTypes.ADD_ARTICLE:
  const newArticle:IArticle = {
    id: ++lastID,
    title: action.article.title,
    body: action.article.body
  }
  const newItems = [...state.articles, newArticle];
  return { articles: newItems };

Finally, I found a solution to my problem. in the reducer function, action have to be type AnyAction

const ArticleReducer = (
  state: ArticleState = initialState ,
  action: ArticleAction | AnyAction
)
Related