On the Roadmap: Exact Objects by Default
Over the next few releases, Flow will be changing the syntax for object types to be exact by default. Support for the new inexact object syntax has recently landed in master and will be available in the next flow release, v0.84.0.
Context
Currently, {foo: number}
is the type for any object which has a property foo
with type number
. {| foo: number |}
is the type for an object which ONLY has a property foo
with type number
. We say the former syntax is an inexact object and the latter is an exact object. For more information on these types, see the Flow docs.
Based on feedback we’ve received over the years, both internally and externally, we’ve found that most developers prefer the safety exact object types provide. We are changing the default object type syntax to express an exact object so that using the preferred type is easier.
New Syntax
In a few releases, Flow will begin to treat {foo: number}
as an exact object. To indicate inexactness, you must add an ellipsis to the end of an object type: {foo: number, ...}
. This new syntax forces the developers to opt in to inexactness.
Rollout Plan
We recognize that this change is going to be extremely disruptive, so we want to do this as incrementally as possible to make it easier for Flow codebases to make the change with us. Here is our complete plan:
tl;dr, we are releasing codemods and flowlints to help you upgrade your codebase.
Step 1 (done in v0.84.0):
- Add support for
...
to indicate explicit inexact object types - Add a default-off flowlint to complain when using implicit inexact object syntax
- Update flow docs
Step 2 (done):
- Update babel, prettier, and recast to add support for the new syntax
- Add a codemod to
flow-upgrade
to change implicit inexact object types into explicit inexact object types.
Step 3 (done):
- Parse object types as exact by default under an
exact_by_default
flag (done in v0.104.0). - Add a default-off flowlint to complain about using the old exact object type syntax
- Update flow docs
Step 4 (done):
- Update babel, prettier, and recast to support the new syntax.
- Add a codemod to
flow-upgrade
to use the new exact object syntax.
Step 5:
- Introduce a lint to enforce
{}
usage for exact objects and disallow{||}
- Turn off parser support for
{| |}
old exact object syntax. - Update babel, prettier, and recast to disallow support for the old syntax.
After step 1, all inexact objects should be explicit, with a lint to prevent against using the implicit inexact syntax. All exact objects should still have the {| props |}
syntax.
To prepare for step 3 it is best to enforce that there are no implicit inexact objects in your codebase. To make this easier, we recommend you use the lints we provide.
After step 3, all inexact objects should be explicit and all exact objects should use the new syntax.
To prepare for step 5, we recommend enforcing that there are no {| exact |}
syntax occurrences in your codebase. To make this easier, we recommend you use the lints we provide.
No two steps will be done within a single release, and we will make sure we don’t release the new versions of flow too far from a babel release.
Conclusion
One of our goals at Flow is to improve the way developers write Javascript. We firmly believe that this change will make code written down the line much safer, precise, and clear.
This blog post is the first of a few that we will publish to help move you through this process as we do here at Facebook.