How to upgrade to exact-by-default object type syntax

Jordan Brown
Jan 29 · 4 min read

Almost a year and a half ago, we announced our plans to make object types exact by default. We’ve consistently heard from our users that they almost always mean to use exact object types, so making them the default makes it easier for developers to express their intent. At Facebook, we already have a few repositories internally using this setting and have seen many open source projects adopt the new syntax as well. Eventually, exact-by-default will be the norm in Flow, so we want to help you get your own codebase onto exact-by-default object types.

Getting your codebase to exact-by-default syntax has three phases:

  1. Upgrading dev tools. Ensure all your tools support the new syntax.
  2. Codemodding. Upgrade your codebase to use the new syntax.
  3. Upgrading dependencies. Upgrade any code dependencies to use the new syntax.

These phases can all be done incrementally, meaning you can make progress over time and do not need to make the switch all in one massive commit. In the rest of the post, I’ll go over each phase and offer some tips in places where we encountered issues.

Upgrading Dev Dependencies

Goal: Make sure all your dev tools can parse the new syntax

JavaScript codebases tend to use a ton of dev tools that parse the code. Here are some examples of tools you may use and the versions to which you you need to upgrade. If you try to use the syntax before you upgrade one of these tools, then that tool will crash with a parse error.

  1. Flow >=0.84.0 (recommend 0.112.0+)
  2. Babel/Babel Parser/Babel Generator >= 7.1.5 (recommend 7.4.5+)
  3. Prettier >= 1.15 (recommend most recent)
  4. babel-eslint >= v11-beta

After you upgrade all of those tools, try putting explicit inexact object types manually in a few spots in your codebase and let your automated tests run. If you get any parser related failures, then the stack traces might be able to guide you towards other packages you need to upgrade.

Codemodding

Goal: Be able to turn on in your flowconfig without getting any errors

After your repo is set up to parse the new implicit inexact object types, you can start codemodding your codebase. Before turning on exact-by-default, you’ll want to make sure that every object type in your codebase is either explicitly exact or explicitly inexact . That way, you can turn on exact-by-default without getting any new errors.

There are two ways to codemod your codebase:

  1. Use flow-upgrade. This will try to upgrade your entire codebase at once. You can invoke to run the codemod.
  2. Use jscodeshift directly. In our experience, it’s easier to use this for larger codebases where you don’t want to run the codemod on the entire codebase in one go. You can use to run the codemod. Get the transform in this gist.

Both of these methods may miss some occurrences of implicit inexact objects. You may need to do a manual pass by-hand after running the codemods.

Tips

  • If you have files shared between different repositories, add to the top of those files. This will make sure that all object types are explicitly exact or explicitly inexact regardless of the exact-by-default settings. This guarantees that your shared files will always mean the same thing across your repositories even if they have different exact-by-default settings.

Upgrading Library Definitions

All of flow-typed was upgraded to use exact-by-default compatible syntax. Any flow-typed definition that is for flow 0.104+ will use only explicit exact object types or explicit inexact object types .

Finishing up the codemods

Once you can turn on in the section in your flowconfig without getting any errors you should move on to the next section. Make sure you push that change to the flowconfig so that other collaborators do not continue to introduce new implicit inexact object types.

Upgrading Dependencies

Goal: Be able to turn on exact-by-default without any errors

Some of your dependencies may ship with their own files and do not have flow-typed definitions. Those projects may not be using exact-by-default, so in those cases you have two options:

  1. Add to all the exported object types in those files and upstream the changes.
  2. Make flow-typed definitions and use there.

Both options will also make it easier for other people in the community to upgrade their own codebases.

To find the dependencies that have those issues, turn on in the section of your flowconfig. If you have no errors, then you’re already set to go. Otherwise, inspect the messages to see which packages in the the errors reference.

Once you’ve fixed all those errors, your codebase is officially exact-by-default!

Conclusion

Good luck with the codemods! When you finish, you’ll have an easier time expressing your intent to Flow without falling into accidental gotchas. If you have any questions, please ask them on this post so that other people having similar issues can see how you solve your problems.

Flow

The official publication for the Flow static type checker for JavaScript. Code faster. Code smarter. Code confidently.

Jordan Brown

Written by

Flow

Flow

The official publication for the Flow static type checker for JavaScript. Code faster. Code smarter. Code confidently.

More From Medium

More from Flow

More on Flow from Flow

More on Flow from Flow

What we’re building in 2020

Andrew Pardoe
Mar 9 · 4 min read

368

More on Flow from Flow

More on Flow from Flow

Improvements to Flow in 2019

Andrew Pardoe
Feb 19 · 4 min read

200

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