- Own property. An "own property" of an object is a property that belongs to the object itself, as opposed to the property being accessible via the prototype chain.
- Object spread. Copies all of the own* properties from an object expression into a location expecting key/value pairs.
* Technically, spread only copies over all properties that are both own and enumerable, but enumerability is usually implied by own-ness. In Flow, we do not distinguish between an own enumerable property and own non-enumerable property.
Previous model was based on the runtime behavior of spreads. This implies the following assumptions:
- Exact object types specify all own properties.
- Inexact object types do not specify own-ness, and only specify a subset of accessible properties. (this was changed in 0.106.0)
This leads to a very understandable behavior when using exact types:
However, inexact types are less straightforward (because of the second assumption about own-ness):
ButtonPropsis inexact, we’re not sure if any of the properties will be copied over in the spread. Because of that, we make all of the properties it copies into
Propsoptional just in case the properties are not own.
Another issue is that inexact objects to not specify all of their properties. Thus Flow makes another conservative approximation when spreading an inexact object types after other properties are already specified:
InjectedPropsis inexact, so it may contain all of the properties specified before it in
Props. Flow will conservatively assume it does to preserve soundness. Since they may be overwritten by properties with unspecified types in
InjectedProps, all of the properties specified before the
InjectedPropstype is spread can only be inferred to have type mixed. And remember,
transparencywill be optional because InjectedProps is inexact.
In the new model, we change our fundamental assumptions about the various different object types in Flow. Most importantly for spreads, our new model has inexact object types specify own properties.
So new assumptions in this model are:
- Exact object types specify all own properties. (unchanged)
- Inexact object types specify a subset of own properties. Some properties may not be included, and we make no assumptions about the own-ness of unspecified properties.
Let's have a look at the previous examples with inexact types:
And now example with the injected props:
It will throw this error (versions before 0.106.0 would be OK with that):
Q: I understand that the solution would be to make InjectedProps exact but what if you cannot? What is the strategy in this case? 🤔
A: It would be pretty funky for someone to inject props and not be able to provide an exact object type. But if that’s the case, you can try spreading InjectedProps before the rest of the props. If that doesn’t work, then the HOC is probably doing something that Flow actually has trouble modeling.