facebook / facebook/flow

Unions of objects and their properties

Aperta
#4,299 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub
Lingua principale
Rust
Stelle
22.3k
Fork
1.9k
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Descrizione

I'm wondering why in flow unions of objects don't match unions of the types within objects. For example:

```
type ActionObject = {| type: 'a' |} | {| type: 'b' |}
type ActionTypesInObject = {| type: 'a' | 'b' |}

const func1 = (arg: 'a' | 'b'): ActionTypesInObject => {
return {
type: arg
}
}

const func2 = (arg: 'a' | 'b'): ActionObject => {
return {
type: arg
}
}
```

func1 works as expected, func2 gives the error that This type is incompatible in the return value ([try flow link](https://flow.org/try/#0C4TwDgpgBAggxsAlgewHYHkBGArCCDOUAvFAN4A+UokAXFAOQCG9U5Avq2ZdRHfZi3YAoHrAQpUAFXAR8ASQw48wYlyoy+zTv0FshQuGnwqAZgFdUcAIyqAFIwBOAc02CGAgJR14SNNMjyirgIxAB8ZEJQUA4QwGYOqBFRUTx0jk6RUHp6BkamFnAATHbprtqe3uJoWMHAhEThpJkxcQlJyalQ6ZnZQA)).

(It seems like potentially something like the `$UnionMap` operator [that has been proposed](https://github.com/facebook/flow/issues/3350) would be useful to avoid duplication in writing these two related types, but I imagine it wouldn't change the behavior).

Is the issue that this would require backtracking or trying different branches [as described here](https://flow.org/blog/2016/07/01/New-Unions-Intersections/)? And if so would it be possible to add this behavior?

My use case is that I was hoping to do something more complicated with combinations of arguments, but was surprised to see that even reducing to the above simpler example doesn't work. What I really want to do is in the context of redux, I would like to type all of my actions and be able to write a generic function that creates an action where the constraints on the parameters need to depend on each other. For example:

```
type ActionObject2 = {| type: 'a', data: 1 |} | {| type: 'b', data: 2 |}

function createAction(typeArg: A, dataArg: D): ActionObject2 {
return { type: typeArg, data: dataArg }
}

createAction('a', 1) // Should work
createAction('b', 2) // Should work
createAction('a', 2) // Should fail, would cause an invalid return function
```

(In this simple example I could rewrite so I'm passing in the object instead of separate args, but more realistically I might be calling the function with typeArg but the dataArg comes from somewhere else like resolving a promise of type `Promise<1>`).

Related issues:
- https://github.com/facebook/flow/issues/2892
- https://github.com/facebook/flow/issues/3929
- https://github.com/facebook/flow/issues/3350

Guida per i contributori

Apri la guida per i contributori

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.