Drop z.undefined()'s optin/optout = "optional"#5899
Closed
colinhacks wants to merge 2 commits into
Closed
Conversation
Bundled into #4769 alongside the legitimate `optin = "optional"` fix for #4768 without separate justification. The test added in the same commit literally has `// z.undefined should NOT be optional` directly above an assertion saying it is. `optout` is read by the object parser's absent-key error-swallow path (#5589) and the tuple parser's `optStart`. Marking `z.undefined()` optout-optional conflates "value type is undefined" with "key may be absent in inferred output," which is upstream of the confusion in #5654 and #5661. Inference doesn't move: `\$ZodUndefinedInternals` doesn't promote `optin`/`optout` to required fields, so `z.object({ a: z.undefined() })` already infers as `{ a: undefined }` regardless. `optin = "optional"` stays — that one is the JSON-schema `required`-array fix from #4768.
Same conflation as the previous commit, on the input side. The motivating JSON-schema bug from #4768 is `.catch()`-specific; the analogous extension to `z.undefined()` was opportunistic. Under strict semantics `z.object({ a: z.undefined() })` infers as `{ a: undefined }` (required key) and the JSON-schema `required` array should agree. Runtime stays permissive — `z.undefined().parse(undefined)` succeeds whether the source was an absent key or an explicit `undefined`.
Contributor
|
New pull request. Leaping into action...
|
Owner
Author
|
Folding the two |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Drops the
inst._zod.optin = "optional"/inst._zod.optout = "optional"assignments in$ZodUndefined.These were bundled into #4769 alongside the
.catch()JSON-schema fix from #4768 without separate justification. The test added in the same commit literally has// z.undefined should NOT be optionaldirectly above an assertion saying it is. The comment was the principled position; the assignments snapshotted whatever the runtime values happened to be after the patch.optoutis read by the object parser's absent-key error-swallow path (#5589) and the tuple parser'soptStart. Markingz.undefined()as optout-optional conflates "value type isundefined" with "key may be absent in inferred output," which is upstream of the confusion threading through #5654 and #5661.optinrides along on the input side —z.object({ a: z.undefined() })infers as{ a: undefined }(required key) under strict semantics, and the JSON-schemarequiredarray should agree.Inference doesn't move.
$ZodUndefinedInternalsdoesn't promoteoptin/optoutto required fields, so neitherz.object({ a: z.undefined() })norz.union([z.string(), z.undefined()])ever extendedOptionalOutSchema/OptionalInSchemastructurally. Only the runtime values were disagreeing with the type.Test changes: four runtime-value assertion flips in
optional.test.tsfor thez.undefined()andz.union([z.string(), z.undefined()])blocks.expectTypeOflines unchanged. 3,763/3,763 pass.