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

Jordan Brown
Jan 29, 2020 · 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.


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.


  • 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!


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.


The official publication for the Flow static type checker…

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

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