我正在尝试学习如何使用Flow,但是我被困在这里。
我有一个redux减速器,可以接受不同类型的动作。每个操作的操作有效载荷都不同,例如:
›v[Ù³›.ˆvíæeË.Ù.öc‘ÊŠh±~Lb‘ÚY¯,u‰%ÛcÒiÒB' Ý}Š©xêKY²,N¯Ó>=Šì/ð÷së©<?‚L‘ KËåž¿—_ÎÛ=—9½ˆžÈ“‹Á¾%Âñÿðó‚$ƒQ$|=…âHC¨Aãï—ÁT²wb¿go¨‹$>¬J+¾êÀ9@AÝȪÈ]ZQÞÂZ¨¾Ù%´Y覆ê¬àþd1 Eá¿1WËǸׇìM„—ú+W3õ†@†%Bú$‰j —?m/Ú·±à¬¹TT¥Zª¯ZVªóIeô—¾’Þš»rÉýŠ{u— Pè»ÈYÈ uzü‰ŸyQÛ8?ƒú<øúå.¼¾§rÙ$Õ)dÑ©ñÜ A8@/ð(.Âï¨fªªj8lP
动作有效载荷的类型如下:
const CreateNewTaskAction = (n: number) => {
return {type: "CREATE", payload: n};
}
const AnotherAction = (r: TaskHandlerType) => {
return {type: "WHATEVER", payload: r}
}
这是我的减速器的一部分:
type TaskHandlerType = {
...
childId: number,
parentId: number,
}
export type ActionType = {
type: string,
payload?: string | number | TaskHandlerType,
}
这是Flow吐出的错误:
const MyReducer = (state: StateType, action: ActionType) = {
switch(action.type) {
...
case "WHATEVER":
....
var newChildrenArray = oldChildrenArray.filter((el) => {
return el != action.payload.childId;
})
....
}
}
它正在检查动作有效载荷为字符串或数字的情况,并警告这些类型不具有属性childId,但这就是为什么我在该分支上使用switch语句的情况,action.payload始终具有childId。
那我该如何告诉Flow?
答案 0 :(得分:1)
编辑:我刚刚注意到您的减速器正在打开 OP评论说这只是问题中的错字。action.payload
。也许OP应该打开action.type
吗?
Flow很难推断出payload
的类型,因为它主要关心action
参数的类型(表示payload?: string | number | TaskHandlerType
),而不是您所关注的值的特定形状重新传递。
原因是:如果添加具有相同类型但有效负载形状不同的另一个动作,将会发生什么?此操作可能类似于:
{
type: 'WHATEVER',
payload: "foo"
}
并且Flow想要确保您的减速器能够处理它,因为根据TaskHandlerType
,此操作是有效的。当然,您不会这样做,因为Redux动作type
必须是唯一的,但是Flow不知道。
基本上有一个假设–只能用特定的type
定义一个动作,而其payload
的形状将始终相同– Flow不可见。我不认为Flow具有任何内置功能可以直接表达这一点……但是,幸运的是,还有另一种解决问题的方法(尽管有更多样板)。
您可以使用union type(类似于payload
中的TaskHandlerType
的类型)来告诉Flow每个特定消息的确切形状。一种方法是这样的:
// Actions
type CreateNewTaskActionType = {| type: "CREATE", payload: number |};
const CreateNewTaskAction = (n: number): CreateNewTaskActionType => ({
type: "CREATE",
payload: n
});
type AnotherActionType = {| type: "WHATEVER", payload: TaskHandlerType |};
const AnotherAction = (r: TaskHandlerType): AnotherActionType => ({
type: "WHATEVER",
payload: r
});
// Types
type ActionType = CreateNewTaskActionType | AnotherActionType;
现在,Flow可以知道带有type: "WHATEVER"
的值肯定具有payload
类型的TaskHandlerType
。
希望这会有所帮助,如果还有其他问题,请发表评论!