尽管使用 "app dispatch" 钩子,但 `dispatch` 方法的类型签名不正确

Improper type signature for `dispatch` method despite using "app dispatch" hook

简介

我正在使用 Redux Toolkit 文档中的 Redux Toolkit to add Redux support to a React application served by a Django app. We're using Typescript, and so we're following the Typescript Quick Start

将 Redux(工具包?)与 Typescript 一起使用的一个重要因素是确保您的 dispatch(...) 方法具有正确的类型签名。如 the docs 中所述,如果您仅使用 react-redux 中的 useDispatch(...) 钩子,

the default Dispatch type does not know about thunks. In order to correctly dispatch thunks, you need to use the specific customized AppDispatch type from the store that includes the thunk middleware types, and use that with useDispatch. Adding a pre-typed useDispatch hook keeps you from forgetting to import AppDispatch where it's needed.

没关系,我遵循了这些说明。我的代码导出了一个新的钩子,就像教程一样:

export type AppDispatch = typeof store.dispatch;
export const useAppDispatch = () => useDispatch<AppDispatch>();

我的问题是:当我使用那个钩子时,dispatch(...) 方法的类型签名仍然不接受 thunk。以下代码:

const dispatch = useAppDispatch();
dispatch(customAction({ ... params ... }));

产生编译错误:

ERROR in [at-loader] ./src/components/Widget.tsx:45:9 
TS2345: Argument of type 'AsyncThunkAction<void, CustomActionParams, {}>' is not assignable to parameter of type 'AnyAction'.
Property 'type' is missing in type 'AsyncThunkAction<void, CustomActionParams, {}>' but required in type 'AnyAction'.

我的问题:为什么类型化的调度方法不能正确接受 AsyncThunkActions?

我尝试过的事情

有趣的是,使用显式参数化的 AppDispatch 类型调用 dispatch(...) 会导致相同的错误。只有用 any 参数化 dispatch(...) 才能消除错误,这显然不理想。

const dispatch = useAppDispatch();
dispatch<AppDispatch>(customAction({ ... params ... })); // same error
dispatch<any>(customAction({ ... params ... })); // error silenced

这让我认为问题是 AppDispatch 没有正确推断它应该采用 AsyncThunkAction 类型,这应该是自动发生的。可能导致这种情况的原因是我的异步操作定义为 within extraReducers,如下所示:

export const customAction = createAsyncThunk(
    "slice/customAction",
    async (payload: CustomActionParams) { ... }
);

export const slice = createSlice({
    name: "slice",
    initialState,
    reducers: {},
    extraReducers: (builder) => {
         builder.addCase(customAction.fulfilled, (state, action) => { ... });
    }
});

我不确定为什么这不会导致类型更新,但这是我必须解决的问题。

与标准设置的差异

关于我的环境的一些事情在理论上也可能导致这个问题,所以为了正确性我将它们包括在这里:

重复的问题:

这个问题最终是由 react-redux@reduxjs/toolkit 包之间的某种版本不匹配引起的。我删除了我的 yarn.lock 并删除了我的 node_modules,然后从头开始重新安装,问题消失了!

(此外,由于 a separate issue installing TypeScript with Yarn 2,我还不得不将 TypeScript 固定在 ~4.1.5。)