如何键入具有相同键但不同值类型的输入和输出对象的函数?

How do I type a function with input and output objects with the same keys but different value types?

基本上,我有一个函数可以将一个对象转换成另一个对象,它就像一本字典,但我不知道如何输入它。

var myFunctions = {
  a: () => something1,
  b: () => something2,
  [...]
}

变成了

var myObject = {
  a: something1,
  b: something2
  [...]
}

我认为您无法使用 Flow 做到这一点。你能得到的最接近的可能是这样的:

function<T>(obj: T): ([key: $Keys<T>]: boolean)

该函数被键入为 return 一个对象,该对象具有与输入对象相同的键,但具有仅限布尔值(例如,您可以指定另一种类型)。很抱歉让您失望了,但通常很难使用 Flow 键入高度动态的代码。

请注意,$Keys 功能未记录,因为它不是 public API 的一部分,因此其行为仅由其实现定义(换句话说,它可以更改随时)。

如果您对 Flow 类型系统的详细信息感兴趣,请在其自己的 /lib 目录中查看 Flow 附带的类型,例如 https://github.com/facebook/flow/blob/master/lib/core.js – 您会看到一些Object.assign 之类的东西是特殊情况,因此您可能无法在自己的代码中重新实现这些东西。

此外,查看 http://sitr.us/2015/05/31/advanced-features-in-flow.html 以了解其他 "dollar features",例如 $Shape$Diff – 它部分已过时,但可以提供一些很好的建议。

@Nikita 给了你目前最好的答案。也就是说,您谈到的用例正在 FlowType 存储库的问题中讨论。它可能很快就会降落。

截至目前,如果您使用的是混合类型,我将退回到 any

function<T>(obj: T): ([key: $Keys<T>]: any)

这样一来,至少键名得到了验证。我希望在 Flow 的更多版本中,这个问题会得到解决。

Flow 0.33+ 可以使用 $ObjMap

type ExtractCodomain = <V>(v: () => V) => V;
declare function f<O>(o: O): $ObjMap<O, ExtractCodomain>;