facebook / facebook/flow

Refinement seems to fail with opaque type aliases

Open
#5,753 0 comments 2 reactions 0 assignees View on GitHub
Typing: opaque types Typing: refinements
Dominant language
Rust
Stars
22.3k
Forks
1.9k
PR merge metrics
No merged PRs in 30d

Description

In a basic case where `strObj` and `numObj` are differentiated by the type of their `thing` property, Flow is able to happily refine things and resolve the `isString` and `isNumber` properties in each branch. ([Try Flow](https://flow.org/try/#0C4TwDgpgBAzsBOB5ARgKygXigbwFBSmAAsBLAOwHMAuWBcigGnyhJgGU7KbkB7HgGwgBDMrgC+Ably5QkKGQCuAWxToseAsXo1FS5BHhMCrAHLL98bn0EjxUmeGgBREsQOrMtJGigAfecqq9gDGPGRwhBARWAAUPGg0Lm7eqACUmAB8OMwwAO6uwURQcWgAdFqU6RoEUMFCMNAALFTMNVDwEMAK8GRQ8ailpuYGUm11DVAA5DA8ShAc8PSTLW0EHV09fWWsC-SjNQAmEABmQgr8wCtQYuJAA))

```js
type strObj = { thing: string, isString: boolean };
type numObj = { thing: number, isNumber: boolean };

type EitherObj = strObj | numObj;

const test = (obj: EitherObj) => {
switch (obj.thing) {
case 4:
return obj.isNumber;
case 'someString':
return obj.isString;
default:
return undefined;
}
}
```

I then define an opaque type alias `A` and a coercion function in another file:

```js
export opaque type A = string;
export default (str: string): A => str;
```

When I attempt to use this in a similar manner, things start to fail:

```js
import type { A } from './alias';
import toA from './alias';

type strObj = { thing: string, isString: boolean };
type numObj = { thing: number, isNumber: boolean };
type aObj = { thing: A, isA: boolean };

type EitherObj = aObj | strObj | numObj;

const test = (obj: EitherObj) => {
switch (obj.thing) {
case 4:
return obj.isNumber; // Property isNumber not found in aObj
case 'someString':
return obj.isString; // Property isString not found in aObj
case toA('alias'):
return obj.isA; // Property isA not found in strObj
// Property isA not found in numObj
default:
}
};
```

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.