Skip to content

multiply a variant's flattened choice into one closed object per combination, where the refusal stood - #230

Merged
eburgos merged 2 commits into
masterfrom
feat/variant-flatten-choice
Aug 8, 2026
Merged

multiply a variant's flattened choice into one closed object per combination, where the refusal stood#230
eburgos merged 2 commits into
masterfrom
feat/variant-flatten-choice

Conversation

@eburgos

@eburgos eburgos commented Aug 8, 2026

Copy link
Copy Markdown
Owner

A struct variant flattening a multi-branch source, or an Option-wrapped one,
was refused: the variant's members are written inside the union member that
carries them, and a single closed object cannot describe a member with more
than one key set. The other two surfaces never had the problem — TypeScript
distributes an intersection over a union, and the JSON document multiplies at
run time — so the refusal was a Zod limitation blamed on the variant.

Zod gets the multiplication now, written out at expansion: one closed object
per combination of the variant's own members with each key set its sources can
write, joined in a union. An Option-wrapped source contributes its keys and
their absence; a multi-branch source one combination per branch; several
sources multiply; a single-branch source collapses to the one object it always
was, byte-identical. The variant still contributes exactly one member to its
enclosing union, so nothing about how the four tagged forms assemble moves —
the internally tagged form drops to a plain union exactly as it already does
for any flattening variant.

The three runtime behaviours the design leans on were measured against zod
4.4.3 before anything was built, not assumed: a union nested in a union accepts
each inner branch and rejects the mixed and partial shapes; a discriminated
union still discriminates when a member's content is itself a union, failing an
unknown discriminator with the single issue at the tag's path; and two
separately written closed objects validate identically. The final schemas were
then re-emitted and run against real serde payloads: every branch of every
multiplied variant accepted, every stale, mixed and unknown-key shape rejected.

What stays refused is the different question it always was: a flattened plain
enum, and a union with a non-object member — sources with no members to merge.
The two refusals this replaces come off with their tests turned into
acceptance; every other flatten fixture is pinned byte-identical.

just check, just quick, just lint-all across all 68 toggles, and the test
powerset across all 68 in four partitions — all green.

eburgos added 2 commits August 7, 2026 20:13
…ination, where the refusal stood

A struct variant flattening a multi-branch source, or an Option-wrapped one,
was refused: the variant's members are written inside the union member that
carries them, and a single closed object cannot describe a member with more
than one key set. The other two surfaces never had the problem — TypeScript
distributes an intersection over a union, and the JSON document multiplies at
run time — so the refusal was a Zod limitation blamed on the variant.

Zod gets the multiplication now, written out at expansion: one closed object
per combination of the variant's own members with each key set its sources can
write, joined in a union. An Option-wrapped source contributes its keys and
their absence; a multi-branch source one combination per branch; several
sources multiply; a single-branch source collapses to the one object it always
was, byte-identical. The variant still contributes exactly one member to its
enclosing union, so nothing about how the four tagged forms assemble moves —
the internally tagged form drops to a plain union exactly as it already does
for any flattening variant.

The three runtime behaviours the design leans on were measured against zod
4.4.3 before anything was built, not assumed: a union nested in a union accepts
each inner branch and rejects the mixed and partial shapes; a discriminated
union still discriminates when a member's content is itself a union, failing an
unknown discriminator with the single issue at the tag's path; and two
separately written closed objects validate identically. The final schemas were
then re-emitted and run against real serde payloads: every branch of every
multiplied variant accepted, every stale, mixed and unknown-key shape rejected.

What stays refused is the different question it always was: a flattened plain
enum, and a union with a non-object member — sources with no members to merge.
The two refusals this replaces come off with their tests turned into
acceptance; every other flatten fixture is pinned byte-identical.

just check, just quick, just lint-all across all 68 toggles, and the test
powerset across all 68 in four partitions — all green.
@eburgos
eburgos merged commit a27d849 into master Aug 8, 2026
@eburgos
eburgos deleted the feat/variant-flatten-choice branch August 8, 2026 00:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant