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

George Edwards picture George Edwards · Jul 31, 2017 · Viewed 15.7k times · Source

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?

Answer

Sergey Karavaev picture Sergey Karavaev · Jul 31, 2017

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