我正在研究具有以下状态的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
为null,并且永远不会进行map
调用,它将返回可接受的结果。但这会将错误放回到有关索引签名的[d]
上。
在这种情况下,有什么方法可以让Flow开心吗?
答案 0 :(得分:0)
只要变量已被修改,Flow都会使类型细化无效。在您的情况下,检查!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]);
}
通过这种方式,您可以访问deals_
,而Flow不会使优化无效。