使用 Flow,有时我想表示某种类型的对象,但其中任何字段都可能是 undefined
或 null
.
例如,验证类型为 T
的对象时,在验证之前我知道我有一些看起来像 T
的东西但可能缺少某些字段。验证成功后,我知道我有一个 T
并且每次使用它们时都不需要对所有字段进行 nullcheck。
type T = { a: number, b: number }
type MaybeT = { a: ?number, b: ?number }
const validate = (candidate: MaybeT): T => {
if (!candidate.a || !candidate.b) {
throw 'Invalid'
}
return { a: candidate.a, b: candidate.b }
}
const maybeT: MaybeT = getInputFromUser()
const t: T = validate(maybeT)
doStuffKnowingAllFieldsOfTAreDefined(t)
显然,MaybeT
的重新定义很冗长,如果我修改T
我现在也要记得修改MaybeT
.
我的问题:
在 Flow 中是否有某种简写形式,例如
$WithAllFieldsMaybe<T>
, 所以我可以导出MaybeT
来自T
无需手动操作?如果不是,是否有更好的模式,无需使用两种不同的类型?据我所知,没有办法让 Flow“知道”
validate
之后所有字段都存在。因为,例如,我可以在validate
之后将字段设置回 null已经运行 - 所以我在这里看不到使用单一类型的方法。
最佳答案
允许任何字段未定义
:
type Person = {
name: string,
age: number
}
type OptionalPerson = $Shape<Person>
允许任何字段为null
:
type Person = {
name: string,
age: number
}
type NullablePerson = $ObjMap<Person, <V>(V) => ?V>
允许任何字段为 undefined
或 null
:
type Person = {
name: string,
age: number
}
type MaybePerson = $Shape<$ObjMap<Person, <V>(V) => ?V>>
如果你需要经常使用这个模式,你可以为自己创建一个可重用的实用程序类型。例如:
type Maybe<T> = $Shape<$ObjMap<T, <V>(V) => ?V>>
type Person = {
name: string,
age: number
}
type MaybePerson = Maybe<Person>
引用资料:
$Shape
:Flow 文档中未记录。您可以在这里阅读:http://sitr.us/2015/05/31/advanced-features-in-flow.html#shapet
$ObjMap
:https://flow.org/en/docs/types/utilities/#toc-objmap
关于Flowtype:所有字段都为 Maybes 的类型的简写,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50553149/