Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

flowtype

Basically, I have a function that will transform an object into a different object, and it's like a dictionary, but I don't know how to type it.

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

gets transformed into

var myObject = {
  a: something1,
  b: something2
  [...]
}
like image 420
kakigoori Avatar asked Mar 09 '16 14:03

kakigoori


2 Answers

With Flow 0.33+ you can use $ObjMap

type ExtractCodomain = <V>(v: () => V) => V;
declare function f<O>(o: O): $ObjMap<O, ExtractCodomain>;
like image 192
gcanti Avatar answered Oct 18 '22 21:10

gcanti


I don't think you can do this with Flow. The closest you can get is probably this:

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

That function is typed to return an object with the same key as input object, but with boolean-only values (as an example, you can specify another type). Sorry to disappoint, but it's hard to type highly dynamic code with Flow in general.

Note that the $Keys feature is undocumented because it's not part of the public API, so its behavior is defined solely by its implementation (in other words, it can change anytime).

If you're interested in the details of Flow's type system, check out the typings that come with flow in its own /lib directory, for example https://github.com/facebook/flow/blob/master/lib/core.js – you'll see that some things like Object.assign are special-cased, so you might not be able to re-implement such things in your own code.

Also, check out http://sitr.us/2015/05/31/advanced-features-in-flow.html for other "dollar features" such as $Shape and $Diff – it's partially outdated, but can give some good pointers.

like image 25
Nikita Avatar answered Oct 18 '22 19:10

Nikita