【问题标题】:Flow errors when dealing with nullable types处理可为空类型时的流错误
【发布时间】:2019-11-28 18:07:54
【问题描述】:

我正在开发具有以下状态的 redux reducer:

 export type WishlistState = {
  +deals: ?DealCollection,
  +previousWishlist: ?(Deal[]),
  +currentWishlist: ?(Deal[]),
  +error: ?string
};
export type DealCollection = { [number]: Deal };

export const initialState: WishlistState = {
  deals: null,
  previousWishlist: null,
  currentWishlist: null,
  error: null
};

export default function wishlistReducer(
  state: WishlistState = initialState,
  action: WishlistAction
): WishlistState {
  switch (action.type) {
    case "GET_DEALS_SUCCESS":
      return { ...state, deals: action.deals };
    case types.GET_WISHLIST_SUCCESS:
      console.log(action);
      const currentWishlist: Deal[] = action.wishlistIds.map(
      // ATTENTION: THIS LINE HERE
        d => state.deals[d]
      );
      return {
        ...state,
        currentWishlist,
        previousWishlist: null,
        error: null
      };
    // ...other cases
    default:
      return state;
  }
}

我用评论标记的行在d 上出现流错误 括号:

Cannot get `state.deals[d]` because an index signature declaring the expected key/value type is missing in null or undefined.

发生这种情况是因为类型注释:deals: ?DealCollection,如果我将行更改为这样会更清楚:

d => state.deals && state.deals[d]

将错误移至state.deals;这个想法是,如果 state.deals 为 null,则回调返回 null(或未定义),这不是 map 回调可接受的返回类型。

我试过了,我真的认为它会起作用:

      const currentWishlist: Deal[] = !state.deals
        ? []
        : action.wishlistIds.map(d => state.deals[d]);

如果没有deals 为空,它将返回可接受的值,并且永远不会到达map 调用。但这会使关于索引签名的错误回到[d]

在这种情况下,有什么方法可以让 Flow 开心吗?

【问题讨论】:

  • WishlistAction的类型定义是什么? { type: string, deals: DealCollection, wishlistIds: number[] } 之类的东西?
  • this 是您问题的一个很好的总结吗?
  • 我想这是一个基本的总结,是的。相关的动作类型(WishlistAction是一个有10+子类型的联合类型)是export type GetWishlistSuccessAction = { type: "GET_WISHLIST_SUCCESS", wishlistIds: number[] };

标签: redux flowtype


【解决方案1】:

只要变量可能已被修改,流程就会使类型细化无效。在您的情况下,检查!state.deals 的想法是一个好的开始;但是,Flow 将使 state.deals 必须是 DealCollection 的事实无效,因为(理论上)您可以在 map 函数中对其进行修改。有关流类型失效的更多信息,请参阅https://stackoverflow.com/a/43076553/11308639

在您的情况下,当您将 state.deals 细化为 DealCollection 时,您可以“缓存”它。例如,

type Deal = string; // can be whatever
type DealCollection = { [number]: Deal };
declare var deals: ?DealCollection; // analogous to state.deals
declare var wishlistIds: number[]; // analogous to action.wishlistIds
let currentWishlist: Deal[] = [];
if (deals !== undefined && deals !== null) {
  const deals_: DealCollection = deals;
  currentWishlist = wishlistIds.map(d => deals_[d]);
}

Try Flow

这样您就可以访问deals_ 而不会使优化失效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-06
    • 2014-01-10
    相关资源
    最近更新 更多