Last active
June 5, 2018 11:44
-
-
Save Ezku/3db645a8b9f9f9835a2b102577f0da5b to your computer and use it in GitHub Desktop.
Opaque type projection does not maintain exactness
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 { | |
type Tagged, // eslint-disable-line import/named | |
tagged | |
} from './tagged'; | |
// I can create tagged values... | |
const taggedString: Tagged<string> = tagged('asdf'); | |
// ...and those values can be used as the type that was provided as the argument to `Tagged`: | |
const untaggedString: string = taggedString; | |
// This works for object types too: | |
const taggedObject: Tagged<{ works: boolean }> = tagged({ works: true }); | |
const untaggedObject: { works: boolean } = taggedObject; | |
// But fails to work for object types flagged exact: | |
const taggedExactObject: Tagged<{| works: boolean |}> = tagged({ | |
works: false | |
}); | |
// $FlowFixMe | |
const untaggedExactObject: {| works: boolean |} = taggedExactObject; | |
// Cannot assign taggedExactObject to untaggedExactObject because inexact Tagged [1] is incompatible with | |
// exact object type [2]. | |
// | |
// [1] 14│ const taggedExactObject: Tagged<{| works: boolean |}> = tagged({ | |
// 15│ works: false | |
// 16│ }); | |
// [2] 17│ const untaggedExactObject: {| works: boolean |} = taggedExactObject; | |
// 18│ |
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 opaque type Tagged<A>: A = A; | |
export const tagged = <A>(value: A): Tagged<A> => value; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment