【问题标题】:Flowtype: shorthand for type with all fields as MaybesFlowtype:所有字段为Maybes的类型的简写
【发布时间】:2021-10-19 02:06:48
【问题描述】:

使用 Flow,有时我想表示某种类型的对象,但其中任何字段都可能是 undefinednull

例如,在验证 T 类型的对象时,在验证之前我知道我有一些看起来像 T 但可能缺少一些字段的东西。验证成功后,我知道我有一个T,并且每次使用它们时都不需要对所有字段进行空检查。

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

我的问题:

  1. 在 Flow 中是否有某种简写形式,例如 $WithAllFieldsMaybe<T>,所以我可以直接从 T 派生 MaybeT 而无需手动操作?

  2. 如果没有,是否有更好的模式,无需使用两种单独的类型?据我所知,没有办法让 Flow“知道”validate 之后的所有字段都存在,因为例如,我可以在 validate 运行后将字段设置回 null - 所以我不知道在这里看不到使用单一类型的方法。

【问题讨论】:

    标签: flowtype


    【解决方案1】:

    允许任何字段为undefined

    type Person = {
      name: string,
      age: number
    }
    
    type OptionalPerson = $Shape<Person>
    

    flow.org/try


    允许任何字段为null

    type Person = {
      name: string,
      age: number
    }
    
    type NullablePerson = $ObjMap<Person, <V>(V) => ?V>
    

    flow.org/try


    允许任何字段为undefinednull

    type Person = {
      name: string,
      age: number
    }
    
    type MaybePerson = $Shape<$ObjMap<Person, <V>(V) => ?V>>
    

    flow.org/try


    如果您需要大量使用此模式,您可以为自己创建一个可重用的实用程序类型。例如:

    type Maybe<T> = $Shape<$ObjMap<T, <V>(V) => ?V>>
    
    type Person = { 
      name: string, 
      age: number 
    }
    
    type MaybePerson = Maybe<Person>
    

    flow.org/try


    参考资料:

    $Shape: Flow 文档中未记录。你可以在这里阅读:http://sitr.us/2015/05/31/advanced-features-in-flow.html#shapet

    $ObjMap:https://flow.org/en/docs/types/utilities/#toc-objmap

    【讨论】:

    • 关闭,但它使属性可选而不是maybe。 (null 不允许为可选)
    • idk,很奇怪,因为它似乎明白属性可以是null/undefined...flow.org/try
    • $ObjMap 似乎没有按预期工作try
    • 嘿@davnicwil 请确保您查看此评论线程,不幸的是,我使用$ObjMap 发布的示例似乎无法正常工作。我可以向flow 提出问题并在此处跟进。
    • 伙计们检查一下,我在 sn-ps 中修复了问题并更新了尝试流程示例。 @Saad 您在括号内缺少 V,例如 (V)。现在可以使用了!
    猜你喜欢
    • 2016-07-26
    • 1970-01-01
    • 2019-04-13
    • 2016-12-07
    • 1970-01-01
    • 2017-07-06
    • 2021-06-03
    • 1970-01-01
    • 2016-01-06
    相关资源
    最近更新 更多