首页 > 解决方案 > Redux 操作打字稿返回类型不起作用

问题描述

所以基本上我试图返回一组函数的类型并能够在我的 redux reducer 中匹配它。

这是我的尝试:

动作.ts

export const SET_CART_ITEMS = "SET_CART_ITEMS";
export const SET_CART_TOTALS = "SET_CART_TOTALS";

export const ADD_CART_ITEM = "ADD_CART_ITEM";
export const REMOVE_CART_ITEM = "REMOVE_CART_ITEM";

export const SET_CART_LOADING = "SET_CART_LOADING";

export function setCart(cart: Cart) {
  return {
    type: SET_CART_ITEMS,
    cart
  } as const;
}

export function setTotals(totals: CartTotal) {
  return {
    type: SET_CART_TOTALS,
    totals
  }
}

export function addCartItem(cart: Cart) {
  return {
    type: ADD_CART_ITEM,
    cart
  } as const;
}

export function removeCartItem(cart: Cart) {
  return {
    type: REMOVE_CART_ITEM,
    cart
  } as const;
}

export function toggleCartLoading(loading: boolean) {
  return {
    type: SET_CART_LOADING,
    loading
  } as const;
}

export type CartActions = ReturnType<typeof setCart>| ReturnType<typeof addCartItem> | ReturnType<typeof removeCartItem> | ReturnType<typeof toggleCartLoading> | ReturnType<typeof setTotals>

减速器.ts

import { 
   CartActions,  
   ADD_CART_ITEM,
   REMOVE_CART_ITEM,
   SET_CART_ITEMS,
   SET_CART_TOTALS,
   SET_CART_LOADING 
} from '../../../actions';

export default (state: CartState = initialState, action: CartActions) : CartState => {
  switch (action.type) {
    case ADD_CART_ITEM:
      return {
        ...state,
        cart: {
          ...action.cart
        }
      }
    case REMOVE_CART_ITEM:
      return {
        ...state,
        cart: {
          ...action.cart
        }
      }
    case SET_CART_ITEMS:
      return {
        ...state,
        cart: action.cart
      }
    case SET_CART_TOTALS:
      return {
        ...state,
        totals: action.totals
      }
    case SET_CART_LOADING:
      return {
        ...state,
        loading: action.loading
      }
    default:
      break;
  }
  return state;
}

这根本不起作用,我得到的错误是在减速器开关中说:

"Property 'cart' does not exist on type 'CartActions'.
  Property 'cart' does not exist on type '{ type: string; totals: CartTotal; }'."


Property 'loading' does not exist on type '{ readonly type: "SET_CART_ITEMS"; readonly cart: Record<string, CartItem>; } | { readonly type: "ADD_CART_ITEM"; readonly cart: Record<string, CartItem>; } | { ...; } | { ...; } | { ...; }'.
  Property 'loading' does not exist on type '{ readonly type: "SET_CART_ITEMS"; readonly cart: Record<string, CartItem>; }'.ts(2339)

我错过了一些明显的东西吗?我真的希望不需要手动通过接口输入所有操作。

灵感来自https://gist.github.com/schettino/c8bf5062ef99993ce32514807ffae849

标签: javascriptreactjstypescriptredux

解决方案


使用您实现的方式CartActions,您应该始终将每个操作的类型分配给它。

例如,您应该更改:

case REMOVE_CART_ITEM:
  return {
    ...state,
    cart: {
      ...action.cart
    }
  }

对此:

case REMOVE_CART_ITEM:
  return {
    ...state,
    cart: {
      ...action.cart
    }
  } as ReturnType<typeof removeCartItem>

或者您可以修改您的CartActionsso 类型作为分隔符:

const enum ActionTypes {
  SET_CART_ITEMS,
  SET_CART_TOTALS,
  ADD_CART_ITEM,
  REMOVE_CART_ITEM,
  SET_CART_LOADING
}



type CartActions =
  | {
      type:
        | ActionTypes.SET_CART_ITEMS
        | ActionTypes.ADD_CART_ITEM
        | ActionTypes.REMOVE_CART_ITEM;
      cart: Cart;
    }
  | {
      type: ActionTypes.SET_CART_TOTALS;
      totals: CartTotal;
    }
  | {
      type: ActionTypes.SET_CART_LOADING;
      loading: boolean;
    };

export function setCart(cart: Cart): CartActions {
  return {
    type: ActionTypes.SET_CART_ITEMS,
    cart
  };
}

export function setTotals(totals: CartTotal): CartActions {
  return {
    type: ActionTypes.SET_CART_TOTALS,
    totals
  };
}

export function addCartItem(cart: Cart): CartActions {
  return {
    type: ActionTypes.ADD_CART_ITEM,
    cart
  };
}

export function removeCartItem(cart: Cart): CartActions {
  return {
    type: ActionTypes.REMOVE_CART_ITEM,
    cart
  };
}

export function toggleCartLoading(loading: boolean): CartActions {
  return {
    type: ActionTypes.SET_CART_LOADING,
    loading
  };
}

推荐阅读