Redux FlowJs:如何键入谓词函数?
我正在尝试在我的应用程序中实现某种类型的通用redux reducer,它应该处理流类型的错误 假设我有FSA的Flowtype定义:Redux FlowJs:如何键入谓词函数?,redux,flowtype,Redux,Flowtype,我正在尝试在我的应用程序中实现某种类型的通用redux reducer,它应该处理流类型的错误 假设我有FSA的Flowtype定义: type Action<P, M = void> = { type: string, payload: P, meta?: M, error?: boolean } 正如文档中提到的,这个函数的主体是一个简单的表达式 最后,我有一个简单的通用操作处理程序: function handle(a: Action<string |
type Action<P, M = void> = {
type: string,
payload: P,
meta?: M,
error?: boolean
}
正如文档中提到的,这个函数的主体是一个简单的表达式
最后,我有一个简单的通用操作处理程序:
function handle(a: Action<string | Error>) {
if (isErrorAction(a)) {
console.log(a.payload.message);
}
}
当我在动作处理程序中内联谓词函数时,一切都正常。所以我可能遗漏了一些关于谓词函数的内容
[]在您最初的示例中,我认为这是Flow谓词函数的一个缺陷,当主语是参数时,它似乎可以正常工作,但当它是参数的成员时就不行了 然而,似乎你想要一些语法糖,在这种情况下,拯救 注意:您必须在使用前测试
有效载荷
或错误
是否存在(truthy),否则它将警告它可能正在处理其他类型,因此在访问a.payload
之前会出现else条件
()
类型成功操作={|
有效载荷:P,
元?:M,
|}
类型FailureAction={|
错误:错误,
元?:M,
|}
类型动作=成功动作|失败动作
功能手柄1(a:动作){
如果(a.错误){
console.error(a.error.message);
}否则{
console.log(a.payload)
}
}
const success={payload:'yay'};
常量错误={error:newerror('bork')};
(成功:成功行动);//通过
(成功:失败行动);//失败:无法将'success'强制转换为'FailureAction',因为对象文字中缺少属性'error'
(错误:FailureAction);//通过
(错误:SuccessAction);//失败:无法将'error'强制转换为'SuccessAction',因为'SuccessAction'中缺少属性'error'`
constboth={payload:'yay',error:newerror('bork')};
(两者:行动);//Fail:(意译)缺少'error'或'payload'
const north={};
(都不是:行动);//Fail:(意译)不精确的文字与'SuccessAction'或'FailureAction'不兼容`
看起来flowtype无法从谓词函数中的对象优化属性:
就我个人而言,我已经结束了以下的感谢您的解决方案,但我与flux标准操作有关,因此操作必须只有
有效负载
属性,错误
属性是可选的,应该是布尔值。但我修改了你的方法:如果meta在成功和失败方面都是同一类型的,那么你不一定需要SM和EM。严格地说,根据flux文档,负载可以是可选的,但按照惯例是一个错误。如果将其设置为有效载荷?
,则在访问action.payload.message
之前需要进行额外检查,例如如果(action.error&&action.payload)
同意,但我有意根据需要添加有效载荷以减少此谓词表达式。这是一种折衷办法,在有效负载为空的情况下,P
可以声明为void
function handle(a: Action<string | Error>) {
if (isErrorAction(a)) {
console.log(a.payload.message);
}
}
console.log(a.payload.message);
^ Cannot get `a.payload.message` because property `message` is missing in `String` [1].
type SuccessAction<P, M = void> = {|
payload: P,
meta?: M,
|}
type FailureAction<P, M = void> = {|
error: Error,
meta?: M,
|}
type Action<P, M = void> = SuccessAction<P, M> | FailureAction<P, M>
function handle1(a: Action<string>) {
if (a.error) {
console.error(a.error.message);
} else {
console.log(a.payload)
}
}
const success = { payload: 'yay' };
const error = { error: new Error('bork') };
(success: SuccessAction<string>); // Pass
(success: FailureAction<string>); // Fail: Cannot cast `success` to `FailureAction` because property `error` is missing in object literal
(error: FailureAction<string>); // Pass
(error: SuccessAction<string>); // Fail: Cannot cast `error` to `SuccessAction` because property `error` is missing in `SuccessAction`
const both = { payload: 'yay', error: new Error('bork') };
(both: Action<string>); // Fail: (paraphrased) either `error` or `payload` is missing
const neither = { };
(neither: Action<string>); // Fail: (paraphrased) inexact literal not compatible with `SuccessAction` or `FailureAction`