首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何创建使用typesafe-actions简化Redux中api请求流处理的通用异步请求epics。

如何创建使用typesafe-actions简化Redux中api请求流处理的通用异步请求epics。
EN

Stack Overflow用户
提问于 2019-11-12 17:07:21
回答 1查看 662关注 0票数 3

我是一个新手,努力理解最好的架构,将epics与异步操作关联在类型记录还原环境中.

是否可以为给定的类型错误操作AsyncCreator实例创建通用异步请求史诗?

我尝试了一下下面的代码,但是丢失了操作payload....only的类型信息,类型属性在我收到的过滤的action....The转换溢出错误上被识别.

代码语言:javascript
复制
Property 'payload' does not exist on type 'ReturnType<[TRequestPayload] extends [undefined] ? unknown extends TRequestPayload ? PayloadAC<TRequestType, TRequestPayload> : EmptyAC<TRequestType> : PayloadAC<TRequestType, TRequestPayload>>'.
代码语言:javascript
复制
const createAsyncEpic = <
  TModel, // generic type for data payload
  TRequestType extends string,
  TRequestPayload extends ApiRequest<TModel>,
  TSuccessType extends string,
  TSuccessPayload extends ApiSuccess<TModel>,
  TFailureType extends string,
  TFailurePayload extends ApiFailure<TModel>
>(
  asyncAction: AsyncActionCreator<
    [TRequestType, TRequestPayload],
    [TSuccessType, TSuccessPayload],
    [TFailureType, TFailurePayload]
  >,
) => {
  const epic: Epic<RootAction, RootAction, RootState, Services> = (
    action$,
    state$,
    { apiService },
  ) =>
    action$.pipe(
      filter(isActionOf(asyncAction.request)),
      switchMap(action =>
        apiService
          .api()
          .all<TModel>(action.payload.url) // property payload unrecognised, only type property recognised here
          .pipe(
            map(response => asyncAction.success(response.data)),
            catchError(error =>
              of(
                asyncAction.failure(error),
              ),
            ),
          ),
      ),
    );
  return epic;
};

是否有人将此作为为每个资源的每个api操作类型创建史诗的替代方案?例如,为每个流显式创建史诗:

  1. FETCH_TODO_REQUEST,FETCH_TODO_SUCCESS,FETCH_TODO_FAILURE,
  2. POST_TODO_REQUEST,POST_TODO_SUCCESS,POST_TODO_FAILURE.,
  3. FETCH_POST_REQUEST,FETCH_POST_SUCCESS,FETCH_POST_FAILURE,
  4. PUT_POST_REQUEST,PUT_POST_SUCCESS,PUT_POST_FAILURE.等

更新信息

再近一点..。修改后的方法函数签名接受数据模型类型。

代码语言:javascript
复制
const createAsyncEpic = <
  TModel // generic type for data payload model
>(
  asyncAction: AsyncActionCreator<
    [string, ApiRequest<TModel>],
    [string, ApiSuccess<TModel | TModel[]>],
    [string, ApiFailure<TModel>]
  >,
) => {
  const epic: Epic<RootAction, RootAction, RootState, Services> = (
    action$,
    state$,
    { courseServices, apiService },
  ) =>
    action$.pipe(
      filter(isActionOf(asyncAction.request)),
      switchMap(action =>
        apiService
          .api()
          .all<TModel>(action.payload.url)
          .pipe(
            map(resp =>
              asyncAction.success({
                request: action.payload, // Api request struct
                response: resp, // Axios Response
              }),
            ),
            catchError(error =>
              of(asyncAction.failure(action.payload.fail(error))),
            ),
          ),
      ),
    );
  return epic;
};

现在得到一个不同的错误:

代码语言:javascript
复制
ERROR in <path>/epics.ts
[tsl] ERROR in <path>/epics.ts(42,5)
      TS2322: Type 'Observable<PayloadAction<TSuccessType, ApiSuccess<TModel | TModel[]>>>' is not assignable to type 'Observable<PayloadAction<actions.FETCH_COURSES_REQUEST, RequestingComponent> | PayloadAction<actions.FETCH_COURSES_SUCCESS, Course[]> | PayloadAction<constants.NOTIFY_ERROR, ErrorReport> | PayloadAction<string, ApiSuccess<Course>> | { ...; } | { ...; } | PayloadAction<...> | PayloadAction<...>>'.
  Type 'PayloadAction<TSuccessType, ApiSuccess<TModel | TModel[]>>' is not assignable to type 'PayloadAction<actions.FETCH_COURSES_REQUEST, RequestingComponent> | PayloadAction<actions.FETCH_COURSES_SUCCESS, Course[]> | PayloadAction<constants.NOTIFY_ERROR, ErrorReport> | PayloadAction<string, ApiSuccess<Course>> | { ...; } | { ...; } | PayloadAction<...> | PayloadAction<...>'.
    Type 'PayloadAction<TSuccessType, ApiSuccess<TModel | TModel[]>>' is not assignable to type 'PayloadAction<actions.FETCH_COURSES_REQUEST, RequestingComponent>'.
      Type 'TSuccessType' is not assignable to type 'actions.FETCH_COURSES_REQUEST'.
        Type 'string' is not assignable to type 'actions.FETCH_COURSES_REQUEST'.

这与史诗类型声明中的RootAction类型匹配吗?

代码语言:javascript
复制
export declare interface Epic<Input extends Action = any, Output extends Input = Input, State = any, Dependencies = any> {
  (action$: ActionsObservable<Input>, state$: StateObservable<State>, dependencies: Dependencies): Observable<Output>;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-11-15 09:45:10

解决了它,并设法使它编译。这是一个类型声明问题。

使用类型记录时,epic签名中声明的操作类型必须是设置中间件时声明的所有操作类型的子集。

我没有实例化新的泛型操作的实例,也没有将它作为类型添加到RootAction(所有动作类型的联合)中。在重构之前,RootAction仍然包含一些来自旧体系结构的旧操作类型。

完成此操作并将我的史诗签名重构为:

  • 指定作为epic
  • 输入的动作类型子集,指定epic

输出的动作类型子集。

我现在有了一个史诗,用于从api中一般地检索资源列表。其他史诗可以跟进补丁,张贴,放置操作等。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58823453

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档