I have had a try with the code below but lose type information on the action payload....only the type property is recognised on the filtered action....The transpilation error that I receive is...Property 'payload' does not exist on type 'ReturnType<[TRequestPayload] extends [undefined] ? unknown extends TRequestPayload ? PayloadAC<TRequestType, TRequestPayload> : EmptyAC<TRequestType> : PayloadAC<TRequestType, TRequestPayload>>'.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 操作类型创建史诗的替代方法?例如,为每个流显式创建史诗:Has anybody achieved this as an alternative to creating an epic for each individual api action type per resource? For example creating an epic explicitly for each flow:[FETCH_TODO_REQUEST、FETCH_TODO_SUCCESS、FETCH_TODO_FAILURE]、[POST_TODO_REQUEST、POST_TODO_SUCCESS、POST_TODO_FAILURE]......、[FETCH_POST_REQUEST、FETCH_POST_SUCCESS、FETCH_POST_FAILURE]、[PUT_POST_REQUEST、PUT_POST_SUCCESS、PUT_POST_FAILURE]........、等更新信息稍微接近....修改方法函数签名以接受数据模型类型.Slightly closer.... modified method function signature to accept data model type. 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;};现在出现不同的错误: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 类型相匹配有关???Is it something to do with looking to match generic action used in the epic with RootAction types in Epic type declaration???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>;}推荐答案已解决并成功编译.这是一个类型声明问题.Solved it and managed to get it compiling. It was a type declarations issue. 使用 Typescript 时,史诗签名中声明的操作类型必须是设置中间件时声明的所有操作类型的子集.When using Typescript, the action types declared in the epic signature must be a subset of all action types that were declared when the middleware was setup.我没有实例化新的通用操作的实例,也没有将它作为类型添加到 RootAction(所有操作类型的联合).在重构之前,RootAction 仍然包含一些来自旧架构的旧动作类型.I had not instantiated an instance of new generic action and I had also not added it as a type to the RootAction(union of all action types). The RootAction still also contained some old action types from older architecture before refactoring.执行此操作后编译的代码并将我的史诗签名重构为:The code compiled after doing this and refactoring my epic signature to:指定作为史诗输入接受的动作类型的子集指定史诗输出的动作类型子集我现在有一个史诗,用于从 api 中检索资源列表.其他史诗可以跟随补丁、发布、放置操作等.I now have an epic for generically retrieving a list of resources from an api. Other epics can follow for patch, post, put operations etc. 这篇关于如何创建使用 typesafe-actions AsyncCreator 的通用异步请求史诗来简化在 Redux 中处理 api 请求流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
10-22 04:05