Is Try running flow 0.29? The string at the bottom of https://flowtype.org/assets/flow.js suggests so, but I ran into an odd difference between it and a fresh flow project running locally.
/* @flow */
type ClipSection = {
clips: []
}
type PlaylistSection = {
playlists: []
}
function foo(section: ClipSection | PlaylistSection) {
if (section.clips) {
console.log(section.clips.length)
} else if (section.playlists) {
console.log(section.playlists.length)
}
}
foo({clips: [1,2]})
foo({playlists: [3,4]})
gives this error:
11: if (section.clips) {
^ property `clips`. Property not found in
11: if (section.clips) {
^ object type
The same code running locally appears to have no issues.
There's two questions here.
flow.js. We should probably mention this on flowtype.org/try/ and maybe even give the option to run against different versions of FlowWhy does your code error on master? Well, Flow's object types are not _exact_ at the moment.
type PlaylistSection = {
playlists: []
}
({ playlists: [] }: PlaylistSection) // This is ok, as expected
({ playlists: [], clips: 123 }: PlaylistSection) // This is also ok
And the reason this is a big deal is that when we do
function foo(section: ClipSection | PlaylistSection) {
if (section.clips) {
console.log(section.clips.length)
}
...
inside the if block we don't actually know for sure that section is a ClipSection. All we know is that there is a truthy clips property, but it could be a PlaylistSection with a clips property.
Exact types will help, because you'll be able to tell Flow something like
type PlaylistSection = $Exact<{
playlists: []
}>
and now we know that a valid PlaylistSection only has a playlists property and will never have a clips property.
Ohhh. Makes sense, thanks for the update.
@gabelevi so in essence you're saying that in the future with the following code:
type ClipSection = $Exact<{
clips: [],
name: string,
}>
type PlaylistSection = $Exact<{
playlists: []
}>
function foo(section: ClipSection | PlaylistSection) {
if (section.clips) {
// flow will know section is a ClipSection
console.log(section.name) // and this will typecheck ok
}
}
@jedwards1211 - I think so, but I'll poke @bhosmer to see if I'm misrepresenting things. Also we haven't completely built the future yet, and sometimes we hone our intuition as we go.
Yeah. Looking forward to this or whatever you guys decide to implement in its place!
@jedwards1211 Hi Andy - just to confirm, Gabe's description has the problem and the intended solution exactly right. (The idea is to follow up later with some syntactic sugar, but the behavior shouldn't change.) cc @gabelevi thanks Gabe!
Closing, seems resolved above.
Most helpful comment
@jedwards1211 Hi Andy - just to confirm, Gabe's description has the problem and the intended solution exactly right. (The idea is to follow up later with some syntactic sugar, but the behavior shouldn't change.) cc @gabelevi thanks Gabe!