项目作者: agiledigital

项目描述 :
An attempt to bring better TypeScript typing to redux-saga.
高级语言: TypeScript
项目地址: git://github.com/agiledigital/typed-redux-saga.git
创建时间: 2019-07-21T02:38:20Z
项目社区:https://github.com/agiledigital/typed-redux-saga

开源协议:MIT License

下载


Typed Redux Saga

npm
Build Status
Type Coverage
codecov
Snyk Vulnerabilities for GitHub Repo

An attempt to bring better TypeScript typing to redux-saga.

Requires TypeScript 3.6 or later.

Installation

  1. # yarn
  2. yarn add typed-redux-saga
  3. # npm
  4. npm install typed-redux-saga

Usage

Let’s take the example from https://redux-saga.js.org/#sagasjs

Before

  1. import { call, all } from "redux-saga/effects";
  2. // Let's assume Api.fetchUser() returns Promise<User>
  3. // Api.fetchConfig1/fetchConfig2 returns Promise<Config1>, Promise<Config2>
  4. import Api from "...";
  5. function* fetchUser(action) {
  6. // `user` has type any
  7. const user = yield call(Api.fetchUser, action.payload.userId);
  8. ...
  9. }
  10. function* fetchConfig() {}
  11. // `result` has type any
  12. const result = yield all({
  13. api1: call(Api.fetchConfig1),
  14. api2: call(Api.fetchConfig2),
  15. });
  16. ...
  17. }

After

  1. // Note we import `call` from typed-redux-saga
  2. import { call, all } from "typed-redux-saga";
  3. // Let's assume Api.fetchUser() returns Promise<User>
  4. // Api.fetchConfig1/fetchConfig2 returns Promise<Config1>, Promise<Config2>
  5. import Api from "...";
  6. function* fetchUser(action) {
  7. // Note yield is replaced with yield*
  8. // `user` now has type User, not any!
  9. const user = yield* call(Api.fetchUser, action.payload.userId);
  10. ...
  11. }
  12. function* fetchConfig() {}
  13. // Note yield is replaced with yield*
  14. // `result` now has type {api1: Config1, api2: Config2}
  15. const result = yield* all({
  16. api1: call(Api.fetchConfig1),
  17. api2: call(Api.fetchConfig2),
  18. });
  19. ...
  20. }

Babel Macro

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:

  1. yarn add --dev babel-plugin-macros

Modify your import names to use the macro:

  1. import {call, race} from "typed-redux-saga/macro";
  2. // And use the library normally
  3. function* myEffect() {
  4. yield* call(() => "foo");
  5. }

The previous code will be transpiled at compile time to raw redux-saga effects:

  1. import {call, race} from "redux-saga/effects";
  2. function* myEffect() {
  3. yield call(() => 'foo');
  4. }

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.

ESLint Rules

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!

Credits

Thanks to all the contributors and especially thanks to @gilbsgilbs for his huge contribution.

See Also