How to type Redux actions and Redux reducers in TypeScript?

后端 未结 20 1998
旧时难觅i
旧时难觅i 2020-12-13 03:39

What is the best way to cast the action parameter in a redux reducer with typescript? There will be multiple action interfaces that can occur that all extend a

20条回答
  •  天涯浪人
    2020-12-13 04:28

    Here's a clever solution from Github user aikoven from https://github.com/reactjs/redux/issues/992#issuecomment-191152574:

    type Action = {
        type: string;
        payload: TPayload;
    }
    
    interface IActionCreator

    { type: string; (payload: P): Action

    ; } function actionCreator

    (type: string): IActionCreator

    { return Object.assign( (payload: P) => ({type, payload}), {type} ); } function isType

    (action: Action, actionCreator: IActionCreator

    ): action is Action

    { return action.type === actionCreator.type; }

    Use actionCreator

    to define your actions and action creators:

    export const helloWorldAction = actionCreator<{foo: string}>('HELLO_WORLD');
    export const otherAction = actionCreator<{a: number, b: string}>('OTHER_ACTION');
    

    Use the user defined type guard isType

    in the reducer:

    function helloReducer(state: string[] = ['hello'], action: Action): string[] {
        if (isType(action, helloWorldAction)) { // type guard
           return [...state, action.payload.foo], // action.payload is now {foo: string}
        } 
        else if(isType(action, otherAction)) {
            ...
    

    And to dispatch an action:

    dispatch(helloWorldAction({foo: 'world'})
    dispatch(otherAction({a: 42, b: 'moon'}))
    

    I recommend reading through the whole comment thread to find other options as there are several equally good solutions presented there.

提交回复
热议问题