这是一个完整的try flow example来说明问题。
export type ActionT<TT: string, PT> = {|
+type: TT,
+payload: PT,
+error?: boolean,
+meta?: any
|}
export type ChangePayloadT = {
+_change: {|
+state: 'PENDING' | 'FULFILLED' | 'REJECTED',
+id: string,
+error?: any,
+message?: string,
|}
}
export type IdPayloadT = {
id: string,
}
type PayloadT = IdPayloadT | ChangePayloadT
type MyActionT = ActionT<'SET' | 'MERGE', PayloadT>
如您所见,MyActionT
可以包含带有id
或_change
对象的有效内容。它不是(?)a disjoint union,因为没有一个属性可以消除歧义。
这似乎应该有效,但不会:
function lookup3 (action: MyActionT): any {
if (action.payload._change) {
// why does this error?
return action.payload._change.id
} else {
return action.payload.id
}
}
任何人都想关心我的原因吗?
答案 0 :(得分:1)
好的,所以解决方案显然涉及使两种类型成为正确的不相交联合:
export type ChangePayloadT = {
+_change: {|
+state: $Keys<typeof asyncStates>,
+id: string,
+error?: any,
+message?: string,
|},
id?: string,
}
export type IdPayloadT = {
+_change?: void,
+id: string,
}
如果第二种类型现在具有明确的void _change
,则流程知道根据_change
的存在与否来区分类型。
Working tryflow耶。 :)