【问题标题】:Recursively Create ReadOnly Object in FlowJS在 FlowJS 中递归创建只读对象
【发布时间】:2018-07-15 23:54:18
【问题描述】:

在 redux 中,状态应该是不可变的。我希望 Flow 阻止任何人改变该状态。所以,给定一个任意深度的对象:

type object = {
  a: {
    b: {
      d: string
    }
  },
  c: number
}

如何创建一个递归只读的新类型,以便我不能这样做:

let TestFunction = (param: $RecursiveReadOnly<object>) => {
  param.a.b.d = 'some string'
}

Flow 的内置 $ReadOnly 实用程序将创建这样的类型,这不是需要的,因为 bd 仍然是可写的:

{
  +a: {
    b: {
      d: string
    }
  },
  +c: number
}

我一直在尝试使用 $Call$ObjMap(i),但我不知道如何在 Flow 中递归地移动对象。我们的目标是:

{
  +a: {
    +b: {
      +d: string
    }
  },
  +c: number
}

【问题讨论】:

标签: recursion redux flowtype


【解决方案1】:

感谢kalley 的解决方案。据我了解,kalley 试图使函数以递归方式接收到的任何对象为只读。因为我真的只需要已知的对象作为参数,所以这非常有效:

// Type definition that works with arbitrary nested objects/arrays etc.
declare type RecursiveReadOnly<O: Object> = $ReadOnly<$ObjMap<O, typeof makeRecursive>>
declare type RecursiveReadOnlyArray<O: Object> = $ReadOnlyArray<$ReadOnly<$ObjMap<O, typeof makeRecursive>>>
type Recursive<O: Object> = $ObjMap<O, typeof makeRecursive>

declare function makeRecursive<F: Function>(F): F
declare function makeRecursive<A: Object[]>(A): $ReadOnlyArray<$ReadOnly<Recursive<$ElementType<A, number>>>>
declare function makeRecursive<O: Object>(O): RecursiveReadOnly<O>
declare function makeRecursive<I: string[] | boolean[] | number[]>(I): $ReadOnlyArray<$ElementType<I, number>>
declare function makeRecursive<I: string | boolean | number | void | null>(I): I

// Usage example.
type obj = {
  a: {
    b: {
      d: string,
    }
  }
}


let TestFunction = (param: RecursiveReadOnly<obj>) => {
  param.a.b.d = 'some string' // Flow throws an error
}

【讨论】:

  • 非常感谢您发布此信息。它在 Flow 0.88.0 之后停止工作,但我设法通过一个小编辑来修复它。将第一个 makeRecursive 声明更改为使用 &lt;I, O, F: I =&gt; O&gt;(F): F 并且它再次工作:) 我有一个工作流尝试,但 URL 太长而无法发布。使用这个 slug 和 bit.ly 来查看它,3CJyoXr
猜你喜欢
  • 1970-01-01
  • 2019-09-03
  • 1970-01-01
  • 1970-01-01
  • 2016-05-26
  • 1970-01-01
  • 1970-01-01
  • 2019-04-02
  • 1970-01-01
相关资源
最近更新 更多