简体   繁体   English

如何在TypeScript中实现redux中间件类

[英]How to implement a redux middleware class in TypeScript

According to the typescript definition of Redux, those interfaces should be implemented to make a middelware: 根据Redux的typescript定义,应该实现这些接口来制作middelware:

/* middleware */

export interface MiddlewareAPI<D extends Dispatch = Dispatch, S = any> {
  dispatch: D
  getState(): S
}

/**
 * A middleware is a higher-order function that composes a dispatch function
 * to return a new dispatch function. It often turns async actions into
 * actions.
 *
 * Middleware is composable using function composition. It is useful for
 * logging actions, performing side effects like routing, or turning an
 * asynchronous API call into a series of synchronous actions.
 *
 * @template DispatchExt Extra Dispatch signature added by this middleware.
 * @template S The type of the state supported by this middleware.
 * @template D The type of Dispatch of the store where this middleware is
 *   installed.
 */
export interface Middleware<
  DispatchExt = {},
  S = any,
  D extends Dispatch = Dispatch
> {
  (api: MiddlewareAPI<D, S>): (
    next: Dispatch<AnyAction>
  ) => (action: any) => any
}

I tried this: 我试过这个:

import { Middleware, Dispatch, AnyAction, MiddlewareAPI } from 'redux';
import { AppState } from 'AppState';

class MiddlewareBase implements Middleware<{}, AppState, Dispatch<AnyAction>> {
  constructor() {
    return (api: MiddlewareAPI<Dispatch<AnyAction>, AppState>) => 
        (next: Dispatch<AnyAction>) =>
           (action: AnyAction) =>
              {
                 // TODO: Do something before calling the next middleware.
                 return next(action);
              };
  }
}

export default MiddlewareBase;

But the compiler complains about this: 但是编译器抱怨这个:

  Type 'MiddlewareBase' provides no match for the signature '(api: MiddlewareAPI<Dispatch<AnyAction>, AppState>): (next: Dispatch<AnyAction>) => (action: any) => any' 

Update: 更新:

It should be a class, not a function. 它应该是一个类,而不是一个函数。 I made a base class so I can inherit them later. 我创建了一个基类,以便稍后继承它们。

You can look at my code . 你可以查看我的代码 Should be something like this: 应该是这样的:

  import { MiddlewareAPI, Dispatch, Middleware, AnyAction } from "redux";

  const callAPIMiddleware: Middleware<Dispatch> = ({
    dispatch
  }: MiddlewareAPI) => next => (action: AnyAction | CallApiAction) => {
    if (!action.meta || !action.meta.callApi) {
      return next(action);
    }

    const { successAction, errorAction, url, params } = action.payload;

    return fetchFn(url, params)
      .then(res => res.json())
      .then(res =>
        dispatch({
          type: successAction,
          payload: res
        })
      )
      .catch(res =>
        dispatch({
          type: errorAction,
          payload: res
        })
      );
  };

There's no such thing as a "redux middleware class" in the first place. 首先,没有“redux中间件类”这样的东西。 So the answer to your how-to question is simply, you can't. 所以你的方法问题的答案很简单,你做不到。

Redux Middleware is a function interface, not a class interface. Redux Middleware是一个功能接口,而不是类接口。 Although in javascript you could force return a function (instead of this object) from a class constructor, you shouldn't with typescript . 虽然在javascript中你可以强制从类构造函数返回一个函数(而不是this对象),但你不应该使用typescript The compiler will probably complain about it cus that's an antipattern, and the class syntax isn't meant for this hacky usage. 编译器可能会抱怨它是一个反模式,并且类语法不适合这种hacky用法。 Even if it doesn't complain, I see absolutely zero gain from such hack. 即使它没有抱怨,我也看到了这种黑客的绝对零收益。

So you want to implement something that's "inheritable". 所以你想要实现“可继承”的东西。 You don't have to go with class syntax. 您不必使用类语法。 You could use, ironically, middleware pattern. 具有讽刺意味的是,你可以使用中间件模式。 Apply base middleware before sub middleware give you inherit-ish effect. 在子中间件之前应用基础中间件给你继承效果。

Now I don't know what you intend to do, so not gonna makeup pointless examples. 现在我不知道你打算做什么,所以不会化妆毫无意义的例子。 If you care to explain what you're trying to do, I'll look into it. 如果你想解释你想要做什么,我会调查一下。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM