Created
March 10, 2020 10:43
-
-
Save sekia/0561ed3ab6b11176dcacaed6d7fe60fb to your computer and use it in GitHub Desktop.
Flow's predicate functions' quirk (checked on flow-bin v0.120.1)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @flow | |
export type A = 'A'; | |
export type B = 'B'; | |
export type T = A | B; | |
export function isA(data: T): %checks { | |
return data === 'A'; | |
} | |
export function isB(data: T): %checks { | |
return data === 'B'; | |
} | |
export const Predicates = { | |
isA, | |
isB, | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @flow | |
import * as Data from './data'; | |
import { isA } from './data'; | |
const x: Data.T = 'A'; | |
// Works as expected. | |
if (isA(x)) { | |
(x: Data.A); | |
} else { | |
(x: Data.B); | |
} | |
// But Namespace-imported predicates don't refine types. | |
if (Data.isA(x)) { | |
// $FlowFixMe | |
(x: Data.A); | |
} else { | |
// $FlowFixMe | |
(x: Data.B); | |
} | |
// Type refinement ability revives by aliasing predicates (why???) | |
const isA_ = Data.isA; | |
if (isA_(x)) { | |
(x: Data.A); | |
} else { | |
(x: Data.B); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment