facebook / facebook/flow

Type refinements with the "in" operator

Open
#7,511 2 comments 0 reactions 0 assignees View on GitHub
feature request Typing: refinements
Dominant language
Rust
Stars
22.3k
Forks
1.9k
PR merge metrics
No merged PRs in 30d

Description

Flow version: 0.93.0

## Expected behavior
I would expect the conditional expression in the function below to be error free (link to [Try Flow](https://flow.org/try/#0GYVwdgxgLglg9mABMOcAUAPAXIg3ogIwEMAnAfhzBAFsCBTExAXwEo8AoRRGYRNAcmIl+3JBkQAyCYgwA6IYgB8iAIxtcTdkyA)):
```js
function foo(x: { bar?: number }) {
if ('bar' in x && x.bar > 1) {}
}
```
## Actual behavior
```
2: if ('bar' in x && x.bar > 1) {}
^ Cannot compare undefined [1] to number [2].
References:
1: function foo(x: { bar?: number }) {
^ [1]
2: if ('bar' in x && x.bar > 1) {}
^ [2]
```
My assumption here is that my `in` operator isn't doing what I hoped it'd do with respect to type refinement. I also tried modeling a disjoint union like the following (link to [Try Flow](https://flow.org/try/#0GYVwdgxgLglg9mABMOcAUAPAXIg3gH0QCMBDAJxzBAFsiBTMxfAXyb3xYEo8AoRRGMERoA5KTIiBSDIgBksxBgB04xAD5EARm65mPZkA)):

```js
function foo(x: {| bar: number |} | {||}) {
if ('bar' in x && x.bar > 1) {}
}
```

But then I get this error instead:

```
2: if ('bar' in x && x.bar > 1) {}
^ Cannot get `x.bar` because property `bar` is missing in object type [1].
References:
1: function foo(x: {| bar: number |} | {||}) {
^ [1]
```

Is there a way to properly type this behavior in Flow?

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.