【问题标题】:Flow types on objects对象上的流类型
【发布时间】:2017-01-25 22:43:13
【问题描述】:

我一直在考虑将 Flow 添加到我的 javascript 项目中。

在某些情况下,我会做这样的事情,我有一个对象。

const myObject = {
    x: 12,
    y: "Hello World"
}

我有一个通用函数,它对对象进行一些映射,保留键但替换值。

function enfunctionate(someObject) {
   return _.mapValues(myObject, (value) => () => value)
}

我希望函数返回 {x: () => number, y: () => string} 类型有没有办法做到这一点?

当然,我可以将它更一般地键入为 {[key: string]: any},但我会失去很多我想通过使用 flow 获得的静态类型。

如果我可以用代码生成或可以工作的宏替换我的少数案例,但我看不出用流来做这件事的好方法。

有没有办法解决这个问题?

【问题讨论】:

标签: javascript flowtype


【解决方案1】:

Flow 能够推断出很多东西。但是,如果要固定类型,则必须自己创建类型。您需要为传递给enfunctionate 的对象创建一个类型,然后指定返回的类型。

您可以使用type alias 键入函数。因此,您可以为该函数创建一个新的显式类型。

function enfunctionate<X, Y>(x: X): Y {
    return _.mapValues(myObject, (value) => () => value)
}

只要知道 X 的类型,就知道 Y 的类型。类型别名、泛型和联合应该能够为您提供所需的灵活性。

但是,我也在想,只要 mapValues 的类型被很好地指定(希望由其他人指定),那么您只需指定 enfunctionate 采用的类型并让 Flow 推断返回类型即可那个函数。

【讨论】:

  • 谢谢,但并没有真正帮助我。我试图输入的函数是为了消除样板文件,所以如果我必须定义类型,它们并没有真正的帮助。此外,_.mapValues 面临与 enfunctioniate 相同的打字问题,因此将问题推到那里确实没有任何帮助。
【解决方案2】:

这是目前你能得到的最好的,虽然它比 {[key: string]: any} 更安全,但仍然有一个 any 参与

function enfunctionate<O: Object>(someObject: O): { [key: $Keys<O>]: (...rest: Array<void>) => any } {
   return _.mapValues(someObject, (value) => () => value)
}

const obj = enfunctionate(myObject)

obj.x() // ok
obj.unknown() // error

编辑:从 v.33 开始,您可以使用 $ObjMap

function enfunctionate<O>(o: O): $ObjMap<O, <V>(v : V) => () => V> {
  return _.mapValues(o, (value) => () => value)
}

【讨论】:

  • 它不是完美的,但比我拥有的要好得多,谢谢!
  • 刚刚添加了一个新的实现(v0.33+)
  • 太棒了!你是怎么知道的?某处有文档吗?
  • 通过阅读提交日志:) github.com/facebook/flow/commit/…
猜你喜欢
  • 2016-11-03
  • 2016-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-28
  • 1970-01-01
  • 2017-09-14
  • 2016-04-27
相关资源
最近更新 更多