Exact object types by default, by default
We announced 5 years ago a plan to eventually make exact object types the default. We are now proceeding with this plan. Starting with Flow 0.200, you must explicitly set either exact_by_default=true
or exact_by_default=false
in the [options]
section of your .flowconfig
, as we have eliminated the default value (which was false
). From Flow 0.202, a default value will be added again, this time as exact_by_default=true
.
In future versions, we will take steps to make exact_by_default=true
the default value if no option is set, and then eventually delete the option completely. Take a look at the “Call to action” section at the end of this post to learn how to update your codebase.
Exact object types
Exact object types permit only the properties listed - no extra properties are allowed. Inexact object types permit additional, unknown properties.
When exact_by_default=false
(previously the default):
type ExplicitlyExact = {|a: number, b: string|};
type ExplicitlyInexact = {a: number, b: string, ...};
type ImplicitlyInexact = {a: number, b: string}; // Inexact
With exact_by_default=true
(the future default):
type ExplicitlyExact = {|a: number, b: string|};
type ExplicitlyInexact = {a: number, b: string, ...};
type ImplicitlyExact = {a: number, b: string}; // Exact
Plan
- Require that
exact_by_default
is set in the.flowconfig
, either totrue
orfalse
, and error if the option is missing. From Flow 0.200 - Remove the above error and make the default, if the option is not specified,
exact_by_default=true
. From Flow 0.202 - Enable the
implicit-inexact-object
lint by default as an error (only in effect whenexact_by_default=false
). This requires either{|foo: T|}
or{foo: T, ...}
. Later this year. - Delete the option and associated lints, no longer allow
exact_by_default=false
. Later this year.
Call to action
If you already have set exact_by_default=true
in your .flowconfig
, you don’t need to take any action at the moment. In the future, when the option is deleted, all you will need to do is delete that line from your .flowconfig
.
If you have not set the above option at all, then to preserve the previous default behavior you can add exact_by_default=false
to your .flowconfig
.
We plan on completely removing the option in the future. To update your codebase so you can enable exact_by_default=true
, read through this blog post from 2020. In short:
- Install
flow-upgrade
(it expectsprettier
as a peer dependency) [npm] - Run
yarn run flow-codemod convertImplicitInexactObjectTypes
(ornpm
equivalent). This will convert all implicit inexact object types, e.g.{a: number, b: string}
, to be explicit, e.g.{a: number, b: string, ...}
- Enable
implicit-inexact-object=error
in the[lints]
section in your.flowconfig
[docs] - Fix any remaining errors that arise, until you have no errors due to the above lint
- Change
exact_by_default
totrue
in your.flowconfig
, and turn off theimplicit-inexact-object
lint - Codemod all explicitly exact object types, e.g.
{|a: number|}
, to remove the|
(now that they are the default). Runyarn run flow-codemod removeExplicitlyExactObjectTypeSyntax
(ornpm
equivalent) to turn that example into{a: number}