Getting error while registering reducers using ActionReducerMap: “not assignable to type 'ActionReducerMap<AppState, Action>”

天大地大妈咪最大 提交于 2021-02-04 22:43:50

问题


Below is simplified version of my Angular 5 application. I have a reducer, which I want to register in my root module. In LINE A I am getting following error:

ERROR in src/app/store/app.reducers.ts(7,14): error TS2322: Type '{ post: (state: State, action: Action) => void; }' is not assignable to type 'ActionReducerMap<AppState, Action>'.
  Types of property 'post' are incompatible.
    Type '(state: State, action: Action) => void' is not assignable to type 'ActionReducer<State, Action>'.
      Type 'void' is not assignable to type 'State'.

app.module.ts : Root module

  imports: [
    ...
    StoreModule.forRoot(reducers)
  ],

store/app.reducers.ts : inside Global store

import {ActionReducerMap} from "@ngrx/store";
import * as fromPost from "../postDir/store/post.reducers";

export interface AppState {
  post:fromPost.State
}
export const reducers: ActionReducerMap<AppState> = { //=======LINE A ======
  post:fromPost.postReducer
};

postDir/store/post.reducers.ts :inside local store

export interface State{
  query:string
  posts:Post[]
}

const initialPostState: State = {
  query:"initial",
  posts:[]
};

export function postReducer(state = initialPostState, action:postActions.PostActions){}

Code works fine if I replace <AppState> in LINE A with <any> Did anyone else face the similar issue? I tried to google but could not find anything significant.


回答1:


Your error message says that property post has the wrong method signature. It is (state: State, action: Action) => void, but should be (state: State, action: Action) => State.

In post.reducers.ts your reducer needs to return the state that is passed into it like this:

export function postReducer(state = initialPostState, action:Action) { 
  return state;
};

The return type is being implicitly inferred from what you are, or in this case aren't, returning.

You could explicitly state the return type with ...): State {... but you should still return the state.




回答2:


I got a similar situation, and after a lot of time, checking my code, I found a missing property return in the switch case actions in the reducer. Make sure you load your previous state with spread operator ...state so you avoid a lot of problems hard to find. In my case I returned all properties but one without first load the previous state. Got the TS2322 error and spent hours to fix and understand what happens. Taking your code as example:

export function postReducer(state = initialPostState, action:postActions.PostActions){

// here you must return the state after an action
   switch (action.type){
       case postActions.ACTION_EXAMPLE:
       return {
              ...state, someProperty: action.payload  // here you load your previous state and change just that one you want

      }
      case postActions.ACTION_02_EXAMPLE:
      return {
              ...state, someProperty: action.payload  // here you load your previous state and change just that one you want

      }
     default:
     return { ...state}
   } 
}

Hope it helps!




回答3:


Answering if someone stumbles upon the same mistake I did. I had this issue using @ngrx/entity when I wanted to reset the state to the initial state on a specific action. I had

I had

on(actions.resetState, () => adapter.getInitialState())

when I should have had the extra properties included like

on(actions.resetState, () => adapter.getInitialState({ foo: 'bar' }))



来源:https://stackoverflow.com/questions/48706362/getting-error-while-registering-reducers-using-actionreducermap-not-assignable

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!