代码之家  ›  专栏  ›  技术社区  ›  davnicwil

流类型:所有字段均为maybes的类型的简写

  •  1
  • davnicwil  · 技术社区  · 6 年前

    在Flow中,有时我想表示某种类型的对象,但任何字段可能在哪里 undefined null .

    例如,在验证类型的对象时 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 我现在还得记住修改 梅贝特 .

    我的问题:

    1. 在Flow中有没有这个的缩写,比如 $WithAllFieldsMaybe<T> ,所以我可以推导 梅贝特 T 不用手动操作吗?

    2. 如果没有,是否有更好的模式来实现这一点,而不需要使用两种不同的类型?据我所知,没有办法让Flow“知道”之后所有字段都存在 validate 因为,例如,我可以在 验证 已经运行了-所以在这里我看不到使用单个类型的方法。

    1 回复  |  直到 6 年前
        1
  •  3
  •   saadq    6 年前

    允许任何字段 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>
    

    flow.org/try


    允许任何字段 未定义 无效的 :

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

    flow.org/try


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

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

    flow.org/try


    参考文献:

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

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