Skip to content

Commit 8a0d645

Browse files
dinwwwhclaude
andauthored
fix(downgrader): make a nullable allOf a oneOf when any member rejects null (#202)
<!-- claude-projects-attribution: {"github_login":"dinwwwh"} --> _Requested by **dinwwwh** · [project thread](https://claude.ai/code/project/chan_01UcKMz91tMarPV1kWLVgLYE?thread=cmsg_01UcKMz91tMarPV1kWLVgLYEJyw1s6rAadV1YjLbH5F8Fh)_ ## What `mergeNullable` makes an `anyOf` null pair a `oneOf` when the other branch rejects null (#126). For an `allOf` branch it looked only at `allOf[0]`, and only when that was a `$ref`. So these stayed an `anyOf` in 3.0: - oRPC's `z.intersection(B, T).nullable()` with `T` registered, which writes `anyOf [{ allOf [B, $ref T] }, { type: "null" }]` (the `$ref` second). - an intersection of two inline objects, `anyOf [{ allOf [object, object] }, { type: "null" }]`. NSwag reads that `anyOf` as an empty class (checked with NSwag 14 C#: the `anyOf` gives an empty `V`, the `oneOf` gives `V : T` holding `B`), which is the reason #126 makes the pair a `oneOf`. ## Fix An `allOf` rejects null when any member does, so every member is checked, following a member's `$ref`. That is exact: null fails the `allOf`, so it matches only the null branch. An `allOf` whose members all admit null stays an `anyOf`. The README row for the `anyOf` null pair now says the pair also becomes a `oneOf` for "an `allOf` with such a member in any place, as Zod writes a nullable intersection". ## Tests New test: the `$ref`-second intersection becomes a `oneOf`, two inline objects become a `oneOf`, and an `allOf` of an untyped member and a `$ref` to a schema that admits null stays an `anyOf`. The test fails on main. `pnpm run check` and `pnpm test` pass (363 tests), and coverage stays at 100%. --- _Generated by [Claude Code](https://claude.ai/code/session_01VVaw7RdCF4usMbdkSRvsKh)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 8e11ec5 commit 8a0d645

3 files changed

Lines changed: 76 additions & 38 deletions

File tree

0 commit comments

Comments
 (0)