'(dispatch: Dispatch<ShopDispatchTypes>) => Promise<void>' 类型的参数不可分配给 'AnyAction' 类型的参数

Argument of type '(dispatch: Dispatch<ShopDispatchTypes>) => Promise<void>' is not assignable to parameter of type 'AnyAction'

错误:

Argument of type '(dispatch: Dispatch<ShopDispatchTypes>) => Promise<void>' is not assignable to parameter of type 'AnyAction'.
useEffect(() => {
  dispatch(GetShops());
}, []);

我正在尝试使用 Typescript 实现 redux-thunk。我使用 react、typescript 和 redux-thunk 创建了简单的购物卡应用程序,但遇到了上述问题。 下面是我的代码片段。如果您需要更多信息,请随时询问。

shops.actionTypes.ts

export const SHOP_LOAD_START = 'SHOP_LOAD_START';
export const SHOP_LOAD_SUCCESS = 'SHOP_LOAD_SUCCESS';
export const SHOP_LOAD_ERROR = 'SHOP_LOAD_ERROR';

export type Shop = {
 id: string;
 name: string;
};

export type ShopType = {
 shops: Shop[];
};

export interface ShopLoadStart {
 type: typeof SHOP_LOAD_START;
}

export interface ShopLoadError {
 type: typeof SHOP_LOAD_ERROR;
}

export interface ShopLoadSuccess {
 type: typeof SHOP_LOAD_SUCCESS;
 payload: ShopType;
}

export type ShopDispatchTypes = ShopLoadStart | ShopLoadError | ShopLoadSuccess;

shops.action.ts

export const GetShops = () => async (dispatch: Dispatch<ShopDispatchTypes>) => {
  try {
    dispatch({
      type: SHOP_LOAD_START,
    });

    const res = await http.get('d9b45894-2549-4e34-9486-7668c2e000a0');

    dispatch({
      type: SHOP_LOAD_SUCCESS,
      payload: res.data,
    });
  } catch (e) {
    dispatch({
      type: SHOP_LOAD_ERROR,
    });
  }
};

shops.reducer.ts

export interface IDefaultState {
  isLoading: boolean;
  shop?: ShopType;
}

export const defaultState: IDefaultState = {
  isLoading: false,
};

const shopsReducer = (
  state: IDefaultState = defaultState,
  action: ShopDispatchTypes
): IDefaultState => {
  switch (action.type) {
    case SHOP_LOAD_START:
      return {
        ...state,
        isLoading: true,
      };
    case SHOP_LOAD_SUCCESS:
      return {
        ...state,
        isLoading: false,
        shop: action.payload,
      };
    case SHOP_LOAD_ERROR:
      return {
        ...state,
        isLoading: false,
      };
    default:
      return state;
  }
};

export default shopsReducer;

store.ts

const Store = createStore(
  rootReducer,
  composeWithDevTools(applyMiddleware(thunk))
);

export type RootStore = ReturnType<typeof rootReducer>;

export default Store;

ShoppingCard.tsx

const ShoppingCard: React.FC<IShoppingCard> = (props: IShoppingCard) => {
  const { label } = props;

  const dispatch = useDispatch();

  const shopsData = useSelector((state: RootStore) => state.shop);

  useEffect(() => {
    dispatch(GetShops()); //Getting error here
  }, []);

}

如果我做错了什么请告诉我。为此花了几个小时,但没有找到任何解决方案。

GitHub: Source code link

问题是 const dispatch = useDispatch(); 只知道来自 redux 核心的基本 Dispatch 类型。 Dispatch 类型不知道 thunk 的存在——它只接受普通的动作对象。因此,当您尝试发送 thunk 时,它(正确地)出错了。

解决方法是遵循我们的“使用 TS”指南,从 store.dispatch 正确推断出 AppDispatch 类型,然后定义 pre-typed 包含 thunk 类型的挂钩:

https://redux.js.org/tutorials/typescript-quick-start

此外,虽然它与问题没有直接关系:您使用的“hand-written”Redux 模式非常过时,而不是我们今天希望人们使用 Redux 的方式。相反,我们现在教授一组更容易学习和使用的“现代 Redux”模式 - Redux Toolkit for logic + React-Redux hooks。今天,我们的官方文档教程将 RTK+hooks 作为标准 Redux 进行教学,但大多数其他教程都已经过时了。请参阅我们的官方文档以了解如何使用 Redux Toolkit,这将大大简化您那里的代码:

https://redux.js.org/tutorials/index