I'm not sure how to write a React observable epic with Redux Toolkit and Typescript.
Suppose I have this authSlice:
import { CaseReducer, createSlice, PayloadAction } from "@reduxjs/toolkit";
type AuthState = {
  token: string,
  loading: boolean,
};
const initialState: AuthState = {
  token: "",
  loading: false,
};
const loginStart: CaseReducer<AuthState, PayloadAction<{username: string, password: string}>> = (state, action) => ({
  ...state,
  loading: true,
  token: "",
});
const loginCompleted: CaseReducer<AuthState, PayloadAction<{token: string}>> = (state, action) => ({
  ...state,
  loading: false,
  token: action.payload.token,
});
const authSlice = createSlice({
  name: 'auth',
  initialState,
  reducers: {
    loginStart,
    loginCompleted,
  },
});
export default authSlice;
and this store:
import { configureStore } from '@reduxjs/toolkit';
import { combineEpics, createEpicMiddleware } from 'redux-observable';
import authEpic from './epics/authEpic';
import authSlice from './slices/authSlice';
const epicMiddleware = createEpicMiddleware();
export const rootEpic = combineEpics(
  authEpic
);
const store = configureStore({
  reducer: {
    auth: authSlice.reducer,
  },
  middleware: [epicMiddleware]
});
epicMiddleware.run(rootEpic);
export type RootState = ReturnType<typeof store.getState>;
export default store;
how should I write this authEpic (I hope the purpose is self-explanatory):
import { Action, Observable } from 'redux';
import { ActionsObservable, ofType } from 'redux-observable';
import { ajax } from 'rxjs/ajax';
import { switchMap } from 'rxjs/operators';
import authSlice from '../slices/authSlice';
export default (action$: ActionsObservable<???>) => action$.pipe(
  ofType(???), /* should be of type loginStart */
  switchMap<???,???>(action => ajax.post( // should be from a loginStart action to {token: string}
    "url", {
      username: action.payload.username, 
      password: action.payload.password 
    }
  )),
  ...
);
I'm totally confused about the ??? that is what should be the types and how redux observable should be linked with redux toolkit.
Any hint?
In redux-toolkit, you should use the action.match function in a filter instead of ofType for a similar workflow, as stated in the documentation.
This example from the docs will work with all RTK actions, no matter if created with createAction, createSlice or createAsyncThunk.
import { createAction, Action } from '@reduxjs/toolkit'
import { Observable } from 'rxjs'
import { map, filter } from 'rxjs/operators'
const increment = createAction<number>('INCREMENT')
export const epic = (actions$: Observable<Action>) =>
  actions$.pipe(
    filter(increment.match),
    map((action) => {
      // action.payload can be safely used as number here (and will also be correctly inferred by TypeScript)
      // ...
    })
  )
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With