Search code examples
typescriptsagaredux-toolkit

How to typescript createAction from redux-toolkit to not get errors


I need to type some props and arguments Here is part of code. How should I write createAction correctly?

const onSubmitHandler = (userFormData: TuserDataFromForm) => {
  console.log("this work");
  // here is error - userFormData
  dispatch(asyncAction(userFormData));
};


function* watchFunc() {
  // here is error - asyncAction.type
  yield takeEvery(asyncAction.type, workFunc);
}


// What should I write instead of any
// to not get error here - dispatch(asyncAction(userFormData)) - in Component
// and here - takeEvery(asyncAction.type, workFunc) - in sagas
const asyncAction: any = createAction("ASYNC_ACTION");

Here is full code:

https://codesandbox.io/s/saga-redux-toolkit-actions-reducers-of-slices-2f7tx?file=/src/redux/actions.ts


Solution

  • The redux toolkit types are written with the thought that you should not define them yourself.

    Write

    const asyncAction = createAction<TuserDataFromForm>("ASYNC_ACTION");
    

    There is no point of specifying a type for the variable there.

    In the future, please check the API documentation in the future - it is almost completely available in TypeScript.

    As for usage in saga, do either of

      yield takeEvery(asyncAction, workFunc);
    // or
      yield takeEvery(asyncAction.match, workFunc);
    

    You also might want to take a look at typed-redux-saga as that integrates a lot better with TS:

    import { take } from "redux-saga/effects";
    
    function* exampleSaga() {
      // cannot be inferred and needs to be manually typed
      const action: IncrementActionType = yield take(slice.actions.incrementBy);
    }
    

    vs:

    import { take } from "typed-redux-saga";
    
    function* exampleSaga() {
      // correctly inferred as { payload: number; type: string; }
      const action = yield* take(slice.actions.incrementBy);
    }