Redux createAsyncThunkFromAPI 包装器问题

问题描述 投票:0回答:1

https://stackblitz.com/edit/react-ts-rkekhf?file=app/redux/asyncThunkFromFetch.ts

我们使用以下助手来创建 thunk:

import { createAsyncThunk } from '@reduxjs/toolkit';
import axios, { AxiosPromise, AxiosResponse } from 'axios';
import { store } from './store';

export const createAsyncThunkFromAPI = <ResponseSchema, RequestParams>(
  typePrefix: string,
  apiFunction: ApiFunction<RequestParams, ResponseSchema>
) => {
  return createAsyncThunk<ResponseSchema, RequestParams>(
    typePrefix,
    async (args, thunkApi) => {
      try {
        const response = await apiFunction(args);
        return response.data;
      } catch (e) {
        return thunkApi.rejectWithValue(e);
      }
    }
  );
};

type ApiFunction<RequestParams, ResponseSchema> = (
  axiosParams: RequestParams
) => AxiosPromise<ResponseSchema>;

export const getMobileOperatorsAPI = (): Promise<AxiosResponse<string[]>> => {
  return axios.get('https://api.com');
};

export default createAsyncThunkFromAPI;

const sliceName = 'mobile-operators';
export const fetchMobileOperators = createAsyncThunkFromAPI(
  `${sliceName}/fetchMobileOperators`,
  getMobileOperatorsAPI
);

store.dispatch(fetchMobileOperators()); //Expected 1 arguments, but got 0.ts(2554)
store.dispatch(fetchMobileOperators({})); //Ouch!!!

我讨厌的一件事是,您不能将零参数传递给助手创建的 thunk 函数。然而,在我们的例子中,使用它而不是来自

createAsyncThunk
的裸
@redux/toolkit

仍然更方便

我试图为 payload creator 创建一个默认参数,但没有成功。但我真的不明白我在这里做什么。

如何调整

createAsyncThunkFromAPI
从API函数推断
args

如何正确地实现相同的想法?

我错过了什么知识可以自己解决这个问题?

typescript redux axios redux-toolkit redux-thunk
1个回答
0
投票

<ResponseSchema, RequestParams = never>

你离得很近,只是错过了一件小东西。您的 thunk 工厂将通过查看

ResponseSchema
的类型来推断泛型
RequestParams
apiFunction
的类型。这个特殊的
apiFunction
没有参数,因此
RequestParams
被推断为
unknown
。我们想确保它被推断为
never
。因此我们添加一个默认值
RequestParams = never
。这意味着当无法推断出
args
时,不会接受任何
RequestParams

export const createAsyncThunkFromAPI = <ResponseSchema, RequestParams = never>(

进行此更改后,所需的用法没有错误,而您的解决方案确实有错误。

store.dispatch(fetchMobileOperators()); // okay!
store.dispatch(fetchMobileOperators({})); // Expected 0 arguments, but got 1.(2554)

还有最后一件事要检查,以确保在有is 必需的参数时它仍然正常工作。我添加了一个额外的例子,果然它工作得很好。缺少参数时会出现错误,提供参数时不会出现错误。

© www.soinside.com 2019 - 2024. All rights reserved.