-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Add one of proptype #295
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
Add one of proptype #295
Conversation
Technically, oneOf accepts any values and compares using `===` at runtime, but most of the time we only care about string literals, for which it's trivial to create a type in flow. Note that if any values in the array passed to oneOf is not a string literal, the inferred type is `any`.
Thank you for your pull request and welcome to our community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file. In order for us to review and merge your code, please sign up at https://code.facebook.com/cla - and if you have received this in error or have any questions, please drop us a line at [email protected]. Thanks! |
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Facebook open source project. Thanks! |
mk_one_of tl (UnionT (r, string_literal :: ts)) | ||
| [], _ -> t | ||
| _ -> AnyT.at vloc in | ||
let reason = mk_reason "oneOf" vloc in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey Sam - I think what you want to do instead here is have the helper build a map of elements to AnyTs, and then build a final EnumT with the result. That way you'll get a single EnumT<{"foo":any; "bar": any; ...}> rather than a union of singleton EnumTs.
And yeah, per your comment, I'd factor a mk_enum_type out of here and convert. It could take a list of strings, and build the key-to-AnyT map out of that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That does make more sense.
Instead of a UnionT of singleton EnumTs, oneOf is now just an EnumT with each specified string value. oneOf, and EnumT, should really support more than just string literals, but doing so currently would involve (1) extending the representable types to include non-string literals and (2) changing EnumT to use something other than object subtyping as it's subtyping mechanism.
@bhosmer Hope the latest commit addresses your comments. Constructing the oneOf EnumT still involves a de-re-structuring of an option type, but that seemed to me the cleanest way to bail out if we encounter something other than a string literal. I imagine some procedural code might allocate less, but this hardly seems like a hot spot. |
Found an issue while I was trying to separate the tests from the existing spread test. If the oneOf proptype isn't required, flow doesn't warn about invalid values. The required/optional/default gymnastics are a little over my head at the moment, so any guidance here is appreciated. |
Hi Sam - sorry for the delay. Thanks for your update! Couple items of feedback:
Anyway, if you could avoid the option repack as described above and add isRequired to your new test, I think we're good to go. And thanks again! Really awesome to have you contributing. Basil |
…ecked Invalid props will pass the type checker for non-required proptypes, which is a bug, but one we will address later. For now, having any oneOf type checking is an improvement.
Pending the test run, I think I addressed your comments. Thanks for your patience and excellent feedback with my contribution. I am definitely interested in spending more time with this proptypes code: adding warnings for proptypes that are unchecked and adding checks to cover more proptypes are both on my list of things to look into. |
Done - thanks again Sam! |
I noticed when digging around the source that a number of PropTypes are not supported, and thought this would be a good place to start contributing.
I tried to follow the style of the existing code, but I would appreciate any formatting critiques.
I'm not super happy with the way I'm creating the string literal EnumT, as I copied it from
convert
. Should this code be factored out into a utility, or is there a better way to go about this?Hope this helps!