An attempt to bring better TypeScript typing to redux-saga.
Requires TypeScript 3.6 or later.
# yarn
yarn add typed-redux-saga
# npm
npm install typed-redux-saga
Let's take the example from https://redux-saga.js.org/#sagasjs
import { call, all } from "redux-saga/effects";
// Let's assume Api.fetchUser() returns Promise<User>
// Api.fetchConfig1/fetchConfig2 returns Promise<Config1>, Promise<Config2>
import Api from "...";
function* fetchUser(action) {
// `user` has type any
const user = yield call(Api.fetchUser, action.payload.userId);
...
}
function* fetchConfig() {}
// `result` has type any
const result = yield all({
api1: call(Api.fetchConfig1),
api2: call(Api.fetchConfig2),
});
...
}
// Note we import `call` from typed-redux-saga
import { call, all } from "typed-redux-saga";
// Let's assume Api.fetchUser() returns Promise<User>
// Api.fetchConfig1/fetchConfig2 returns Promise<Config1>, Promise<Config2>
import Api from "...";
function* fetchUser(action) {
// Note yield is replaced with yield*
// `user` now has type User, not any!
const user = yield* call(Api.fetchUser, action.payload.userId);
...
}
function* fetchConfig() {}
// Note yield is replaced with yield*
// `result` now has type {api1: Config1, api2: Config2}
const result = yield* all({
api1: call(Api.fetchConfig1),
api2: call(Api.fetchConfig2),
});
...
}
You can use the built-in babel macro that will take care of transforming all your effects to raw redux-saga effects.
Install the babel macros plugin:
yarn add --dev babel-plugin-macros
Modify your import names to use the macro:
import {call, race} from "typed-redux-saga/macro";
// And use the library normally
function* myEffect() {
yield* call(() => "foo");
}
The previous code will be transpiled at compile time to raw redux-saga effects:
import {call, race} from "redux-saga/effects";
function* myEffect() {
yield call(() => 'foo');
}
This gives you all the benefits of strong types during development without
the overhead induced by all the calls to typed-redux-saga
's proxies.
In order to avoid accidentally importing the original effects instead of the typed effects, you can use this ESLint plugin: https://github.com/jambit/eslint-plugin-typed-redux-saga
It includes an auto-fix option, so you can use it to easily convert your codebase from redux-saga to typed-redux-saga!
Thanks to all the contributors and especially thanks to @gilbsgilbs for his huge contribution.
- https://github.com/danielnixon/eslint-config-typed-fp
- https://github.com/danielnixon/eslint-plugin-total-functions
- https://github.com/danielnixon/readonly-types
- https://github.com/jonaskello/eslint-plugin-functional
- https://github.com/gcanti/fp-ts
- https://github.com/plantain-00/type-coverage