-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unsealed objects are not type-checked #2327
Comments
Also, inconsistency: this works fine: declare function test(t: { x: number }): void;
const c = {};
test(c); // error
c.x = 1;
// no error if we call test here But this works incorrectly: declare function test(t: { x: number }): void;
const c = {};
test({ x: c.x }); // no error |
This is definitely surprising behavior, but this is actually working as designed. Here's a relevant snippet from the docs
This means that Flow will not catch read-before-write order problems for unsealed objects like this: var o = {};
(o.p: number); // read
o.p = 0; // write is consistent, no error But it will catch inconsistent read/writes: var o = {};
(o.p: string); // read
o.p = 0; // error: number -> string If you only read and write properties, this behavior is fairly predictable. You've astutely noted one inconsistency with this story, though. Checking an unsealed object against another object is "strict" whereas unsealed object property read/writes are "non-strict." var o: { p: string } = {}; // error: property `p` not found You might (reasonably) interpret the above as similar to a property read. It would be reasonable under that interpretation to not error here. Currently we special-case this particular pattern because a) this pattern is less common and b) it's especially surprising. This non-strict read/write behavior is important to support a common JS idiom of building objects incrementally. This doesn't just happen with objects, but also ES3-style classes, where methods are incrementally added to the function's prototype object. For some added color, I have a few diffs in the pipeline that work in this part of the code, although those diffs largely maintain existing behavior including everything I've described here. Hope this helps clear things up! |
Can you provide an example? I actually do exactly that and I can't see how strictness can get in the way. Maybe such behaviour can be implemented with an explicit type (e.g. |
Fixed if you enabled |
This passes:
This doesn't:
The text was updated successfully, but these errors were encountered: