Search code examples
angulartypescriptngrxngrx-store

Property 'payload' does not exist on type 'Action' when upgrading @ngrx/Store


I have the @ngrx/store package in my angular (4.x) app, and am upgrading from v2.2.2 -> v4.0.0. I can see that the migration notes say:

The payload property has been removed from the Action interface.

However, the example they give seems completely counter intuitive (in my view...).

I have a reducer function which looks like this:

export function titleReducer(state = { company: 'MyCo', site: 'London' }, action: Action): ITitle {
    switch (action.type) {
        case 'SET_TITLE':
            return {
                company: action.payload.company,
                site: action.payload.site,
                department: action.payload.department,
                line: action.payload.line
            }
        case 'RESET':
            return {
                company: 'MyCo',
                site: 'London'
            }
        default:
            return state
    }
}

Which as expected now throws typescript error:

[ts] Property 'payload' does not exist on type 'Action'

But I have no idea from the migration guide what this should be changed too. Any ideas?


Solution

  • You can create your own action type that has a payload defined, check the example app for reference:

    class AddBookAction implements Action {
        readonly type = ADD_BOOK;
    
        constructor(public payload: Book) {}
    }
    

    Then use that type in the reducer:

    function reducer(state = initialState, action: AddBookAction): State
    

    Action could be dispatched like this:

    this.store.dispatch(new AddBookAction(book));
    

    Note also that the example app combines all the action types that a reducer can take into a single union type:

    export type Actions =
        | AddBookAction
        | AddBookSuccessAction
    
    export function reducer(state = initialState, action: Actions): State