我正在尝试在我的应用程序中实现某种通用的redux reducer,它应该处理带有流类型的错误flux standard actions。
假设我有FSA的Flowtype定义:
type Action<P, M = void> = {
type: string,
payload: P,
meta?: M,
error?: boolean
}
其中P
可能是错误的实例。另外,我有自定义predicate function来检测错误操作:
function isErrorAction<P, M>(a: Action<P, M>): boolean %checks {
return a.payload instanceof Error;
}
正如文档中提到的,这个函数的主体是简单的表达式。
最后,我有一个简单的通用动作处理程序:
function handle(a: Action<string | Error>) {
if (isErrorAction(a)) {
console.log(a.payload.message);
}
}
但Flowtype抱怨:
console.log(a.payload.message);
^ Cannot get `a.payload.message` because property `message` is missing in `String` [1].
当我在动作处理程序中内联谓词函数时,一切正常。所以我可能错过了一些关于谓词函数的东西。
[Qazxswpoi]
在你的原始例子中,我认为这是Flow的谓词函数的失败,当主语是参数时似乎工作得很好,但是当它是参数的成员时它似乎不行。
然而,似乎你想要一些语法糖,在这种情况下,try it out救援!
注意:您必须在使用前测试Disjoint Unions或payload
是否存在(真相),否则它将警告它可能正在处理另一种类型,因此在访问error
之前的其他条件。
(Qazxswpoi)
a.payload
看起来flowtype无法从谓词函数中的对象中细化属性:Try it out
就个人而言,我最终跟随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`
的github tread