Flow: `$Reduce` utility type feature request?

Created on 30 May 2018  路  4Comments  路  Source: facebook/flow

Is there any way something like a $Reduce utility type for iterable types could be bought into Flow? It would be nice to be able to map over a bunch of types and create, for example, a union type from them, or perhaps an object type but with different keys. I'm finding this would be really useful when trying to keep tagged union types DRY.

feature request

Most helpful comment

6622 would be another use case for this feature.

All 4 comments

I鈥檓 not sure in exactly what sense you want to reduce over types, but
for the particular case of creating a large union of types you might
find the $Values type constructor useful:

class Apple {}
class Orange {}
class Brick {}

type NamedFruits = {
  APPLE: Apple,
  ORANGE: Orange,
};

type Fruit = $Values<NamedFruits>;

const apple: Fruit = new Apple();
const orange: Fruit = new Orange();
const brick: Fruit = new Brick();  // error!

The NamedFruits type declared in this example can often be a useful
thing to have: for instance, in conjunction with $ObjMap, as
in this example.

If techniques like this aren鈥檛 sufficient, then perhaps you could
provide an example of what you鈥檇 like to see?

I have a situation where a $Reduce function might work nicely.

I have a question out on StackOverflow but I'm starting to think it's not currently possible: https://stackoverflow.com/questions/50707318/flow-how-can-i-type-an-object-that-consists-of-objects-nested-within-it/50721085#50721085

Question reproduced below for example function in a Reduce like situation:

How would I properly type the following (not correctly typed) function?

function myfunction<O, T:{ +[string]: any => O }>(inputObject: T): { ...O } {
    let ret = {};

    Object.values(inputObject).forEach(x => {
            const out = inputObject[x]();
            ret = {
                ...ret,
                ...out
            }
    });

    return ret;
}

I want to be able to take in an input such as

let inputObj = {
    call1: () => ({
        response1: {
        }
    }),
    call2: () => ({
        response2: {
        }
    })
}

myfunction(inputObj)

And get the output type which in this case would be

type outputObj = {
    response1: {},
    response2: {}
}

I've tried combinations of the utility functions such as $ObjMap<>, but the problem is that I don't know how to make a new object that raises the nested keys up to a higher level.

This is a slightly contrived function. Ultimately I'm trying to type a React HOC that injects extra props into a component, but the injected props are a function of the input to the HOC that take the shape of the inputObject specified above.

6622 would be another use case for this feature.

This is a good example of what I was aiming for with this feature.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

bennoleslie picture bennoleslie  路  3Comments

ctrlplusb picture ctrlplusb  路  3Comments

mjj2000 picture mjj2000  路  3Comments

cubika picture cubika  路  3Comments

damncabbage picture damncabbage  路  3Comments