首页 > 解决方案 > 带有 TypeScript 的 Redux Toolkit:如何正确键入异步 thunk 的返回值

问题描述

我有这样的异步重击

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

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

<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)

类型“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();
  }
);

error但是,当我访问调度返回的响应时,编译器仍然对此不满意。

类型“AsyncThunkAction<UpdateIndexingConfigurationResponse, UpdateIndexingConfigurationRequest, {}>”上不存在属性“错误”。

不知道我在这里缺少什么。在这种情况下,如何正确输入响应?

也是一个小问题,TS 编译器也对我大喊大叫await dispatch(updateIndexingConfig(...)),说

'await' 对此表达式的类型没有影响。ts(80007)

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

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

标签: reactjstypescriptreduxredux-toolkit

解决方案


dispatch没有考虑 thunk 的类型,因此返回类型输入错误。请使用文档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

推荐阅读