Refinement seems to fail with opaque type aliases
- 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
Assessment
This issue has not been assessed yet.