Quick simple guide on making Redux-Observable works with TypeScript
This is a guide I written on stack overflow, which I plan to rewrite it into a simple post.
You can checkout React Redux Typescript Guide for the details in here for all the standard way of doing when using React, Redux and Redux-Observable.
Introduction
This guide I would like to talk a bit about using Redux-Observable alongside with TypeScript and make the types work out of the box.
I will be using typesafe-actions library to achieve the types. (GitHub for typesafe-actions)
Actions
Instead of declaring interface (types) expressively, (something like below)
export interface LoginSuccessAction extends Action {
type: LoginActionTypes.LOGIN_SUCCESS_ACTION;
payload: {
loginToken: string;
};
}
export function loginSuccess(loginToken: string): LoginSuccessAction {
return {
type: LoginActionTypes.LOGIN_SUCCESS_ACTION,
payload: { loginToken },
};
}
use typesafe-actions library without declaring any interface.
actions/login/LoginActions.ts
import {action} from "typesafe-actions"
export function loginSuccess(loginToken: string) {
return action(LoginActionTypes.LOGIN_SUCCESS_ACTION, { loginToken });
}
Then, all the login actions are being exported out in the model file.
actions/login/LoginActionsModel.ts
import * LoginActions from "./LoginActions";
import { ActionCreator } from "typesafe-actions";
export type LoginActionCreator = ActionCreator<typeof LoginActions>
Then export out all the actions as AllActions.
actions/index.ts
import { LoginActionCreator } from "./login/LoginActionModel";
export default type AllActions = LoginActionCreator
Epics
In the epics, import following library.
import { Epic } from "redux-observable";
import { isOfType } from "typesafe-actions";
import { filter } from "rxjs/operators";
Then simply use Epic to declare your types.
export const loginUserEpic: Epic<AllActions> = (action$) =>
action$.pipe(
filter(isOfType((LoginActionTypes.LOGIN_ACTION))),
switchMap((action: LoginAction) =>
ajax({
url,
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: { email: action.payload.username, password: action.payload.password },
}).pipe(
map((response: AjaxResponse) => loginSuccess(response.response.token)),
catchError((error: Error) => of(loginFailed(error))),
),
),
);
Where the Epics is from redux-observable library, AllActions are the actions that is input and output of the epics.
The types is as follows:
Epic<InputActions, OutputActions, Store>
Epic<Actions(Input&Output)>
In case you want to use store from redux, you need a RootState (from root reducer)
export const someEpic: Epic<AllActions, AllActions, RootState> = (action$, store$)
=> action$.pipe(
filter(isOfType(SOMETYPE)),
mergeMap(action => {
const a = store$.value.a;
return someActions(a, action.payload.b);
})
Leave Quick simple guide on making Redux-Observable works with TypeScript to:
Read more #javascript posts
Best Posts From Johnson Lai
We have not curated any of superoo7's posts yet. But you can encourage our curation team to review posts by visiting them regularly and by referring other readers. Because we give priority to frequently read content.
More Posts From Johnson Lai
- WHive Smart Contract Analysis
- Created Hive-Price-Feed
- Created Hive-Price-Feed
- Joining Steemfest 4 community
- [Tutorial] Ruby On Rails Push Notification
- Use "Do Not Track" on your web browser
- Build A Full Front End Stack with Quasar Framework and Vue
- Done my personal portfolio with Steem Blockchain and Quasar Framework
- Unexpected down time
- Side to side comparison of Digital Ocean and AWS LightSail