-
Notifications
You must be signed in to change notification settings - Fork 5
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 nonStrict
modifier for record
runtypes
#90
Conversation
nonStrict
modifiernonStrict
modifier for record
` runtypes
nonStrict
modifier for record
` runtypesnonStrict
modifier for record
runtypes
@hoeck I have updated the PR description with more details and an overview of the functionality. This is based on my understanding at the moment, but any of it can change based on discussions we have. I will add my questions and comments about the code itself and the way |
General question about non-strictness, records, and 'combination' runtypes ( Similar to I haven't thought through all the possibilities, but I can take a union of records and/or a discriminated union as an example. (But // (A) union of records -> no `fields`
st.union(st.record({ name: st.string() }), st.record({ lastname: st.string() }))
// (B) discriminated union -> `unions`, but no `fields`
st.union(
st.record({ type: st.literal("standard"), accessLevel: st.number() }),
st.record({ type: st.literal("pro"), accessLevel: st.number(), admin: st.boolean() })
) Would we expect to be able to apply Does this make sense? Does it make sense, for example, to have a union of nonStrict runtypes vs apply nonStrict to a union? To be clear, at this point, I'm not trying to say what does and does not make sense, but rather just wanting to have the conversation. (Also consider the various |
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.
Wow! Great work. You've nailed all the important details (nesting, using a symbol for the metadata, ...).
Please merge it if you are happy with my comments.
Things we (I) need to do in order to release this:
- support non-strict in
intersection
s (that runtype looks quite messy to me and maybe needs a little refactoring) - update the changelog (I need this when I update simple-runtypes at work so I know what has changed between versions)
- update the readme: remove sloppyRecord, add nonStrict documentation
Again, HUGE thanks for the hard and detailed work you've put into this PR!
Sorry for delay on this. Planning on giving it some time this weekend. |
TODO
|
- Remove reference to `sloppyRecord` - Add section about `nonStrict` - Various other formatting and style changes
I think I didn't answer this question? Or did I already?
Right, not all records implement the "reflection" interface with #89 was made by coworker while we were translating some untyped Ruby code into Typescript and stumbled across the need to use omit on a non-record runtype.
Nah that's fine to suggest stuff, no need to be so defensive I am always open to discuss stuff :D and in that case it completely makes sense. Given your specific example with unions, it can become quite tricky to exactly mimic Typescripts behavior: So it looks like we need to keep union type info in addition to |
READMEI have updated the README: removing sloppyRecord, adding nonStrict, and various other stylistic and formatting changes. I fully understand that style and formatting are subjective, so feel free to let me know if you'd prefer non/any of the changes to be reverted. Most are an attempt at making the formatting more consistent throughout, and a few are things I noticed a long the way. I changed a few things in the Usage Examples section to try to introduce concepts before they are used, and also to separate out different examples. Other notes:
CHANGELOGNext is adding an entry to the CHANGELOG. This would be v7.2.0, right? IntersectionsYou mentioned this previously: "support non-strict in intersections (that runtype looks quite messy to me and maybe needs a little refactoring)" I don't feel like I have the requisite knowledge yet to be able to look into this. So, just checking: will you be looking at this? |
👍 that looks good thanks!
Yes, please leave that for now - in a future version nonStrict should work on any type.
Looks good to me 👍
Right, unless we decide to remove sloppyRecord in the same release then it would be 8.0.0. Or release that together with the record->object rename to not release too many major versions? But for now you can also use "unreleased" in the changelog. I made the habit of adding all changes immediately to the log as I tend for forget what was all done once I'm ready to release a new version.
Yeah will do that thanks for the reminder! |
Done 👍
Maybe?:
I can understand the concern to not release too many major versions, but I also don't think it's worth bundling up too many changes into one release. Obviously up to you at the end of the day though 😄
🙂 |
Sounds like a good compromise 👍 |
🎉 @hoeck Thanks for all the guidance and help on this 😄 |
Fixes:
sloppyRecord
looses its sloppyness when modified with partial, pick or omit #23Description
Context
The default mode of a
record
runtype is strict, where strictness refers to how a runtype treats excess keys in untrusted input data:Because the
record
runtype is strict by default, excess keys in its input will be treated as an error:simple-runtypes
currently also offers a non-strict version of therecord
runtype, which is called thesloppyRecord
runtype. Because it is non-strict,sloppyRecord
ignores excess keys:nonStrict
modifierA non-strict modifier allows strict
record
runtypes to be changed (modified) into non-strict versions, as opposed to having a separate non-strict runtype (seesloppyRecord
above). Some of the reasons why this is desirable are outlined in #68. One of these reasons is that it allows for separation between the record's definition and the way the record is parsed. The modifier approach is similar to the way thepick
,omit
, andpartial
runtypes work (they modify a record runtype in order to create a new runtype).record
runtypes continue to be strict by default, and thenonStrict
modifier is used on an existing record runtype to create a new, non-strict record runtype. For example:Notes on capabilities and limitations
strict and
nonStrict
can be used in the same runtypesnonStrict
is not recursivenonStrict
can only be applied to recordsRecord runtypes include:
record
,pick
,omit
,partial
,intersection
(of two records).Compatibility
sloppyRecord
can still be used. Under the hood, asloppyRecord
just uses thenonStrict
functionality.