Image for post
Image for post
Photo by Jason Yu on Unsplash

New Flow Errors on Unknown Property Access in Conditionals

Gabriel Levi
Mar 16, 2018 · 4 min read

TL;DR: Starting in 0.68.0, Flow will now error when you access unknown properties in conditionals.

Flow already disallows accessing unknown properties outside of conditionals

Let’s say I want to write a function that takes a person object and returns the name of that person’s dog. If that person doesn’t have a dog, it will return undefined:

If the object person doesn’t have a property nameOfDog, then the expression person.nameOfDog will evaluate to undefined. So this code does work as expected. However, Flow 0.67.1 will produce the following error.

We require our users to annotate what properties might exist. The following would produce no Flow errors:

Why does Flow disallow this valid JavaScript pattern? It is because we found that spelling mistakes in property names are a very common source of bugs in JavaScript. By banning accessing unknown properties, we can catch errors like this:

Existence testing in conditionals

However, until 0.68.0, Flow would allow you to test the existence of unknown properties in conditionals. So Flow would allow you to write

and if you accidentally wrote

Flow would miss your spelling mistake.

If you tested whether an unknown property existed, Flow would refine that unknown property to mixed. So you could write

and Flow would infer that,

  • if person.dog exists, it has the type mixed.
  • If person.dog.name exists, it has the type mixed.

But again, Flow would fail to point out spelling mistakes. And furthermore, Flow would allow code that was trivially incorrect, like accessing imaginary properties on Number.prototype!

We‘ve changed this behavior!

Now accessing unknown properties in conditionals behaves like accessing them outside of conditionals.

produces the error

and

produces the error

To fix that second example to work with Flow 0.68.0, I would change it to

Union types

You can test the existence of a property which exists in some branch of the union inside the conditional. With Flow 0.68.0, the following code

produces the error

Accessing catName and dogName are allowed, because they each appear in the union. But accessing zebraName is disallowed because it doesn’t appear anywhere.

Classes

Before Flow 0.68.0, the following would have produced no errors

But in Flow 0.68.0, you’ll get the error

The fix is to either declare name in Animal.

Or to use instanceof

Feedback welcome!

We made this change after receiving a lot of feedback about Flow missing spelling mistakes in property names. Love this new behavior? Hate this new behavior? Let us know!

Flow

The official publication for the Flow static type checker…

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store