【问题标题】:Typescript: How to type the Dispatch in ReduxTypescript:如何在 Redux 中键入 Dispatch
【发布时间】:2019-02-23 18:38:02
【问题描述】:

例如我想在这里删除dispatch: any

export const fetchAllAssets = () => (dispatch: any) => {
  dispatch(actionGetAllAssets);
  return fetchAll([getPrices(), getAvailableSupply()]).then((responses) =>
    dispatch(actionSetAllAssets(formatAssets(responses))));
}

我在上面调度了 2 个操作,actionsGetAllAssetsactionsSetAllassets

以下是两者的接口和 actionCreators:

// Interfaces
interface IActions {
  GET_ALL_ASSETS: string;
  SET_ALL_ASSETS: string;
  GET_MARKET_PRICES: string;
  SET_MARKET_PRICES: string;
  ADD_COIN_PORTFOLIO: string;
  ADD_COINS_PORTFOLIO: string;
  UPDATE_COIN_PORTFOLIO: string;
  REMOVE_COIN_PORTFOLIO: string;
} 

interface IGetAllAssets {
  type: IActions['GET_ALL_ASSETS'];
  loading: boolean;
}

interface ISetAllAssets {
  type: IActions['SET_ALL_ASSETS'];
  assets: IAsset[];
  loading: boolean;
}

// ACTION CREATORS
const actionGetAllAssets = () => ({
  type: Actions.GET_ALL_ASSETS,
  loading: true
});

const actionSetAllAssets = (data: any) => ({
  type: Actions.SET_ALL_ASSETS,
  assets: data,
  loading: false
});

然后我尝试了以下方法:

export const fetchAllAssets = () => (dispatch: IGetAllAssets | ISetAllAssets) => {
  console.log('fetchAllAssets', dispatch);
  dispatch(actionGetAllAssets);
  return fetchAll([getPrices(), getAvailableSupply()]).then((responses) =>
    dispatch(actionSetAllAssets(formatAssets(responses))));
}

但是它会产生这个 Typescript 错误:

无法调用类型缺少调用签名的表达式。输入'IGetAllAssets | ISetAllAssets' 没有兼容的调用 signatures.ts(2349)

想法?还是有其他方式来键入调度事件?

【问题讨论】:

  • 当您将调度定义为 any 时,它是否正常工作?
  • @KaranGarg 是的,它适用于任何人,但这是一个 hack
  • 你可以试试(dispatch: IGetAllAssets | ISetAllAssets)而不是Dispatch<IGetAllAssets> | Dispatch<ISetAllAssets>

标签: javascript typescript redux react-redux dispatch


【解决方案1】:

Redux 类型有一个可以使用的通用 Dispatch<A> 类型,其中 A 是操作类型。

export const fetchAllAssets = () => (dispatch: Dispatch<IGetAllAssets | ISetAllAssets>) => {
  // ...
}

【讨论】:

  • 我使用了这种方法,但结合了一个定义为联合类型的可重用 Action 类型。这样它就只是(dispatch: Dispatch&lt;Action&gt;)
【解决方案2】:

我还有一点!

Dispatch 是一个事件函数,所以让它工作:

interface IAllAssets {
  type: IActions['GET_ALL_ASSETS'];
  assets?: IAsset[];
  loading: boolean;
}

// ACTIONS
// Fetch assets from Nomics API V1.
export const fetchAllAssets = () => (dispatch: (arg: IAllAssets) => (IAllAssets)) =>
{
   dispatch(actionGetAllAssets());
   return fetchAll([getPrices(), getAvailableSupply()]).then((responses) =>
       dispatch(actionSetAllAssets(formatAssets(responses))));
}

但是我仍然想创建一个dispatch type,类似于:

interface IAllAssetsDispatch {
  dispatch: (arg: IAllAssets) => (IAllAssets)
}

export const fetchAllAssets = () => (dispatch: IAllAssetsDispatch) => {

但这会产生同样的缺少调用签名错误。

明白了!

忘记了 type 这就是我需要使用的功能,而不是 interface

type DispatchAllAssets = (arg: IAllAssets) => (IAllAssets);

type DispatchMarketPrices = (arg: ISetMarket) => (ISetMarket);

type DispatchAddCoin = (arg: ICoinPortfolio) => (ICoinPortfolio);

type DispatchAddCoins = (arg: ICoinsPortfolio) => (ICoinsPortfolio);

// ACTIONS
// Fetch assets from Nomics API V1.
export const fetchAllAssets = () => (dispatch: DispatchAllAssets) => {
  dispatch(actionGetAllAssets());
  return fetchAll([getPrices(), getAvailableSupply()]).then((responses) =>
    dispatch(actionSetAllAssets(formatAssets(responses))));
}

// Fetch USD, USDC & USDT markets to filter out Exchange List.
export const fetchMarketPrices = (asset: string) => (dispatch: DispatchMarketPrices) => {
  dispatch(actionGetMarketPrices);
  return getMarkets().then((res) => {
    if (res && res.marketUSD && res.marketUSDC && res.marketUSDT) {
      const exchangesForAsset = combineExchangeData(asset, res);
      return dispatch(actionSetMarketPrices(exchangesForAsset));
    }
    else {
      return dispatch(actionSetMarketPrices([]));
    }
  });
}

【讨论】:

    猜你喜欢
    • 2016-05-30
    • 2020-04-13
    • 1970-01-01
    • 2020-02-03
    • 1970-01-01
    • 1970-01-01
    • 2019-08-24
    • 2021-01-01
    • 2021-12-20
    相关资源
    最近更新 更多