我为调度到reducer的操作定义了一个类型:
type RemoveQuestionAction = {
type: 'REMOVE_QUESTION',
questionId: number,
docTypeId: number,
};
type QuestionAction =
| RemoveQuestionAction
| ...
reducer检查每个动作的类型:
const questions = (
state : QuestionState = defaultState,
action : QuestionAction
) : QuestionState => {...};
字段questionId
在几个数组过滤器中引用:
case REMOVE_QUESTION: {
return {
...state,
byId: state.allIds
// Throws error
.filter(id => id !== action.questionId)
.reduce((col, id) => ({
...col,
[id]: state.byId[String(id)],
}), {}),
// Throws error
allIds: state.allIds.filter(id => id !== action.questionId),
};
}
这会引发action.questionId
的类型错误。
但是,如果操作中的值放在变量中,则很高兴:
case REMOVE_QUESTION: {
let { questionId } = action; // Ok with this
return {
...state,
byId: state.allIds
.filter(id => id !== questionId)
.reduce((col, id) => ({
...col,
[id]: state.byId[String(id)],
}), {}),
allIds: state.allIds.filter(id => id !== questionId),
};
}
为什么我不能直接使用action
的值?
这是REPL。
它在REPL中按预期执行,真的很奇怪,因为我看不出有什么不同......
Flow是版本6.23
答案 0 :(得分:1)
action.questionId
会引发错误。在action
进行细化后执行RemoveQuestionAction
的箭头函数时,Flow无法确定filter()
是否仍为case REMOVE_QUESTION:
。
我们人类知道filter()
立即执行给定的回调函数,例如id => id !== action.questionId
,因此根本无法修改action
。但是,从flow的角度来看,filter()
只是一个将回调函数作为参数的函数,而回调函数可以像addEventListener()
那样稍后执行。如果稍后可以执行回调函数,则有可能修改action
并且类型细化不再成立。这就是为什么flow在这种情况下使action
的类型细化无效的原因。