带有 TypeScript 的 Redux 工具包:如何​​从异步 thunk 中正确键入 return 值

Redux Toolkit w/ TypeScript: how can I properly type the return value from an async thunk

我有一个像这样的异步 thunk

export const updateIndexingConfig = createAsyncThunk(
  "settings/updateIndexingConfig",
  (config: UpdateIndexingConfigurationRequest) => {
    return sdkClient.updateIndexingConfiguration(config).promise();
  }
);

更新请求可以 return 一条错误消息(如果有的话)。 updateIndexingConfiguration.promise() 将要 return 一个承诺。当用户点击这个按钮时它被调度

<Button
  onClick={async () => {
    if (!isFormValid()) return;
    const updateIndexingConfigResponse = await dispatch(
      updateIndexingConfig(constructUpdateIndexingConfigRequest(indexingConfig))
    );
    if(updateIndexingConfigResponse.error) {
      // ... show error banner 
    } else {
      window.location.href = "#/settings/";
    }
  }}
>
  Update
</Button>;

TypeScript 编译器在这一行给我这个错误 if(updateIndexingConfigResponse.error)

Property 'error' does not exist on type 'AsyncThunkAction<any, UpdateIndexingConfigurationRequest, {}>'.

我想是因为SDK没有定义响应类型。但是通过阅读它的文档,我知道当出现问题时,响应可能会出现错误消息。所以我赶紧自己做了一个

interface UpdateIndexingConfigurationResponse {
  error?: {
    message: string;
  };
  [key: string]: any;
}

然后我在 thunk

添加了它
export const updateIndexingConfig = createAsyncThunk(
  "settings/updateIndexingConfig",
  (config: UpdateIndexingConfigurationRequest): UpdateIndexingConfigurationResponse => {
    return sdkClient.updateIndexingConfiguration(config).promise();
  }
);

然而,当我在调度的 returned 响应上访问 error 时,编译器仍然对此不满意。

Property 'error' does not exist on type 'AsyncThunkAction<UpdateIndexingConfigurationResponse, UpdateIndexingConfigurationRequest, {}>'.

不确定我在这里遗漏了什么。在这种情况下,如何正确输入响应?

又是一个小问题,TS编译器也在await dispatch(updateIndexingConfig(...))跟我吼,说

'await' has no effect on the type of this expression.ts(80007)

但我知道它确实有效果。在这种情况下 await

顺便说一句,请不要质疑代码是否有效,或者即使 sdkClient.updateIndexingConfiguration(config).promise() return 是一个承诺,我测试过它并且我知道它有效。只是缺少打字,这是我的问题。

在我看来,您的内部函数可能没有返回 Promise,而 createAsyncThunk 需要返回 Promise。

您的 dispatch 没有考虑 thunk 的类型,因此 return 类型输入错误。请使用 the documentation:

中描述的商店中的实际 Dispatch 类型
import { configureStore } from '@reduxjs/toolkit'
import { useDispatch } from 'react-redux'
import rootReducer from './rootReducer'

const store = configureStore({
  reducer: rootReducer
})

export type AppDispatch = typeof store.dispatch
export const useAppDispatch = () => useDispatch<AppDispatch>() // Export a hook that can be reused to resolve types