Skip to content
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

Record Flow type improvements #1870

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

mwiencek
Copy link

Fixes #1722

I moved the Values type parameter to Record<Values>, so calling Record(foo) can infer Values from foo and now returns RecordFactory<Values>.

This is a breaking change, though I believe it provides much better type checking for typical uses (and fixes at least one TODO). Unfortunately, this PR introduces issues when calling RecordInstance methods from a subclass (which I'm not sure how to fix), but that probably isn't super common, so the tradeoff might be worth it.

This allows for better type inference of the resulting RecordFactory.

Fixes immutable-js#1722
Comment on lines 154 to 157
setName(name: string): this & TPerson {
// $FlowIssue[incompatible-return]
return this.set('name', name);
}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the new changes, Flow doesn't like the this & TPerson return type one bit:

Error ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈ type-definitions/flow-tests/record.js:155:12

Cannot return this.set(...) because: [incompatible-return]
 • Either RecordInstance [1] is incompatible with this [2].
 • Or TPerson [3] is incompatible with this [2].

     type-definitions/flow-tests/record.js
 [3]  147│ const PersonRecord = Record<TPerson>(defaultValues);
         :
      152│   }
      153│
 [2]  154│   setName(name: string): this & TPerson {
      155│     return this.set('name', name);
      156│   }
      157│ }
      158│

     type-definitions/immutable.js.flow
 [1] 1659│   set<K: $Keys<T>>(key: K, value: $ElementType<T, K>): this & $ReadOnly<T>;



Found 1 error

@@ -170,23 +169,6 @@ person.get('unknown');
// $FlowExpectedError[prop-missing]
person.set('unknown', 'Thales');

// Note: not <TPerson>
Copy link
Author

@mwiencek mwiencek Jul 31, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what the use case here is (and PersonRecord is no longer parameterized anyway) so I removed the test altogether. If someone can explain the use case I can perhaps update it instead. :)

Edit: To be clear, the test right above this one is now class Person extends PersonRecord, so it's "without types" (though that isn't really possible anymore) now, and the .get('unknown'); there errors, which I think is correct, but which contradicts this test (at "Note: no error").

@jdeniau jdeniau added the flow label Sep 16, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Record definitions are sloppy
2 participants