facebook / facebook/flow

Unions of objects and their properties

Offen
#4,299 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
Vorherrschende Sprache
Rust
Sterne
22.3k
Forks
1.9k
PR-Merge-Kennzahlen
Keine gemergten PRs in 30 T.

Beschreibung

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

Beitragsleitfaden

Beitragsleitfaden öffnen

Bewertung

Dieses Issue wurde noch nicht bewertet.

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.