类型“(dispatch: Dispatch) => void”的参数不可分配给“AnyAction”类型的参数

Adi*_*tov 11 async-await reactjs redux redux-thunk react-redux

错误本身:

(alias) deleteCategory(id: number): (dispatch: Dispatch<AnyAction>) => void
import deleteCategory
Argument of type '(dispatch: Dispatch) => void' is not assignable to parameter of type 'AnyAction'.
  Property 'type' is missing in type '(dispatch: Dispatch) => void' but required in type 'AnyAction'.ts(2345)
Run Code Online (Sandbox Code Playgroud)

有问题的代码:

export function getCategoryList(
  categories: CategoryType[],
  dispatch: Dispatch
) {
  return categories.map((category: CategoryType) => ({
    ...category,
    onDelete: () => {
      dispatch(deleteCategory(category._id)); //FIXME: Fix this. Error Appears here
    },
  }));
}
Run Code Online (Sandbox Code Playgroud)

删除类别的实现:

export const deleteCategory = (id: number) => (dispatch: Dispatch) => {
  deleteCategoryAPI(id)
    .then(() => {
      dispatch({
        type: DELETE_CATEGORY,
        category: id,
      });
    })
    .catch((error) => console.error(error));
};
Run Code Online (Sandbox Code Playgroud)

删除类别API的实现:

export async function addCategoryAPI(category: CategoryType) {
  return fetch(`${API_URL}/categories`, {
    method: "POST",
    body: JSON.stringify(category),
    headers: { "Content-Type": "application/json; charset=UTF-8" },
  }).then((response) => response.json());
}
Run Code Online (Sandbox Code Playgroud)

我在这里使用有问题的代码:

const categoryList = getCategoryList(categoryState, dispatch);
...
return (
    <List
      dataSource={categoryList}
      renderItem={({ name, onDelete }) => (
        <List.Item>
          <CategoryItem name={name} onDelete={onDelete} />
        </List.Item>
      )}
    />
  );
Run Code Online (Sandbox Code Playgroud)
function CategoryItem({ name, onDelete }: categoryItemPropsType) {
Run Code Online (Sandbox Code Playgroud)
export type categoryItemPropsType = {
  name: string;
  onDelete: () => void;
};
Run Code Online (Sandbox Code Playgroud)

可能有什么问题?为此花了几个小时。有趣的是,当我调用dispatch(deleteCategory(category._id))功能组件中的其他地方时,例如它可以正常工作。非常感谢!

fly*_*rum 5

我最初可以想到几种不同的方法,您可以考虑这样做,具体取决于您愿意投入多少精力,您想要的香草实现有多真实,以及您想要的打字准确程度。

  1. 最简单的实现和最真实的API(但打字很差):

    // create your own dispatch function reference with custom typings
    export const dispatchStore = store.dispatch as typeof store.dispatch | Dispatch<any>
    
    // use custom typed dispatch (unfortunately, you can pass it almost `any`thing)
    dispatchStore(myThunk('id123'))
    
    Run Code Online (Sandbox Code Playgroud)
  2. 一个简单的实现,但需要输入每个调用(并且仍然有很差的输入):

    // optional
    export const dispatchStore = store.dispatch
    
    // type each dispatch as any (not good if you need to use 'abort', etc)
    dispatchStore(myThunk('id123') as any)
    
    Run Code Online (Sandbox Code Playgroud)
  3. 该项目特定于 Redux Toolkit,但可以轻松应用于第三方库(例如 Redux)的大多数 TypeScript 键入问题。在使用 的情况下redux-toolkit,可以创建对 或 的引用configureStorecreateSlice并根据您的选择操作输入。在下面的代码中,我将 createSlice 函数包装在 中createSlicePlus,在幕后添加了一堆方便的逻辑,并增强了 args 和返回类型。

    // convenience `request` wrapper around store `dispatch` that abstracts the rest
    const promise = counter.request.decrementThunk(500)
    // even the RTK thunk promise is typed appropriately
    promise.abort()
    
    Run Code Online (Sandbox Code Playgroud)

第三个示例的代码可以在 Github 上找到。