facebook / facebook/flow

Flow does not refines type of class union as it does with types

Offen
#4,353 1 Kommentar 2 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
bug Typing: refinements
Vorherrschende Sprache
Rust
Sterne
22.3k
Forks
1.9k
PR-Merge-Kennzahlen
Keine gemergten PRs in 30 T.

Beschreibung

Here is an [example of failure](https://flow.org/try/#0PQKgBAAgZgNg9gdzCYAoVBjGBDAzrsAeQGswAebAPjAG9UwwBLXEgLjABcAnAVwFN6YAG7YY-VtlQBfdFjwEAoly5wu5AB7U6DZmzBRRuAQz7LVrddPQcAngAc+YAEp9cPGBw0AaMFTABeImIKagAfMCUVLjJNQVQ+dTtVTww4ADtcFIALbEY0gO9fHwAjSgAKQSh2MpExPnZsAEoA6hc3DxiSyi9BLld3DnY2gc7fSlRGof6O9S6W2kFGKDAyvvaOADpdYmbtBjA+jh4ufKhV6c3a-kbBKTA+GCMF-YO+I5PX9durIA) that I'd expect to work:

```js
/* @flow */

class Ok {
isOk: true
value:a
}

class Error {
isOk: false
error:x
}

type Result = Ok | Error

export const chain = (
f: (value: a) => Result,
result: Result
): Result => {
if (result.isOk) {
return f(result.value)
} else {
return result
}
}
```

It fails to refine Result to `Ok` and `Error` by `isOk` sentinel field as following erros seem to indicate:

```
20: return f(result.value)
^ property `value`. Property not found in
20: return f(result.value)
^ Error
22: return result
^ Ok. This type is incompatible with
18: ): Result => {
^ union: type application of polymorphic type: class type: Ok | type application of polymorphic type: class type: Error
22: return result
^ Ok. This type is incompatible with
18: ): Result => {
^ union: type application of polymorphic type: class type: Ok | type application of polymorphic type: class type: Error

25:1
```

What's interesting that if I [change classes to type definitions](https://flow.org/try/#0PQKgBAAgZgNg9gdzCYAoVAXAngBwKZgDyA1mADwCGAfGALxgDeqYYAlgM4kBcYGATgFc8AGmZgAbhRhCuFVAF902fGACifPnD7kAHjXpMWHbmChT2IsXg1auOhUtwEASnnYCYGXcLDU6RYkoaAB81Gz4yPTFUPB0cLS8AYzgAO3YkgAsKVhT-SJ8KHwAjKgAKMSgeUslpPB4KAEo6Gld3T3ywEtEWPjcPDB5W-o7qVAbBvvadYv0aQzYoMFLetowAOmNiJvmevAwBPlyoZcn1mqEGsXkwPBgLRjFd-cOwFf6rhyA) everything works as expected, but [same error is present if interfaces are used](https://flow.org/try/#0PQKgBAAgZgNg9gdzCYAoVBLAdgFwKYBOUAhgMZ5gDyA1mADzEB8YA3qmGBgM40BcYOAgFc8AGnZgAbsRgjexVAF902fETIUAogQJwC9AB7M2HbnzAkYXMRMK6CvA0vQ4AngAcKAJTxchMHENRMCYwAF4qagZmAB8wbXs6IwlUPAN3PUDSOCwuLIALYmxwoJDggCNGAAoJKH4q6Vk8fmIASnDmHz8ApIrGcQ4CX38cfi6R3pDGVFax4Z6DPo7WCQwoMCqh7pwAOjNqdpMOMCGcIQIsC0353caRVolFMDwrCiPBvDOLk5vH5yA)

For whatever reason [type refinements via switch](https://flow.org/try/#0PQKgBAAgZgNg9gdzCYAoVBLAdgFwKYBOUAhgMZ5gDyA1mADzEB8YA3qmGBgM40BcYOAgFc8AGnZgAbsRgjexVAF902fETIUAogQJwC9AB7M2HbnzAkYXMRMK6CvA0vQ4AngAcKAJTxchMHENRMCYwAF4qagZmAB8wbXs6IwlUPAN3PUDSOCwuLIALYmxwoJDggCNGAAoJKH4q6Vk8fmIASnDmHz8ApIrGcQ4CX38cfi6R3pDGVFax4Z6DPo7WCS4EDBxSfKqh7pwAOjNqdpMOMFJiawFhZtQASDOwIZwhAiwLHfmDxpFWiQ4ACZ4EgjXj3R7PV7vXYjCTKZRAA) instead of `if` seems to work in all cases:

```js
/* @flow */

interface Ok {
isOk: true,
value:a
}

interface Error {
isOk: false,
error:x
}

type Result = Ok | Error

export const chain = (
f: (value: a) => Result,
result: Result
): Result => {
switch(result.isOk) {
case true:
return f(result.value)
default:
return result
}
}
```

Beitragsleitfaden

Beitragsleitfaden öffnen

Bewertung

Dieses Issue wurde noch nicht bewertet.

Neue Issues direkt in Ihr Postfach

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