valibot icon indicating copy to clipboard operation
valibot copied to clipboard

[to-json-schema] Nullable generates anyOf instead of oneOf

Open vladshcherbin opened this issue 2 months ago • 4 comments

Seems logical that nullable should generate oneOf instead of anyOf:

const schema = object({
  name: nullable(string())
})

console.dir(toJsonSchema(schema), { depth: null })

output:

Image

zod blog post has similar example with oneOf union - https://zod.dev/json-schema?id=nullability#nullability

valibot - 1.1.0 @valibot/to-json-schema - 1.3.0

vladshcherbin avatar Sep 15 '25 16:09 vladshcherbin

Oh ffs, zod also has this bug - https://github.com/colinhacks/zod/issues/5100 🤦‍♂️

vladshcherbin avatar Sep 15 '25 17:09 vladshcherbin

Hey 👋 thank you for reaching out! Why do you think oneOf is better than anyOf in this case? I think Valibot also uses anyOf for the internal validation. Otherwise the validation would probably fail you write a schema like:

const Schema1 = v.union([v.string(), v.null()]);
const Schema2 = v.nullable(Schema1);

fabian-hiller avatar Sep 16 '25 02:09 fabian-hiller

@fabian-hiller please have a look at https://github.com/colinhacks/zod/issues/5100 and bot response there. Being not a native English speaker, I believe I won't be able to better summarize the idea 😅

For me oneOf is more explicit saying this or that, that's why I was surprised it was not used. anyOf kinda fits too, it just sounds a bit more permissive.

A bit offtopic:

Image

congrats on 2mil downloads and thank you for the great library, such a joy to use it everywhere!

vladshcherbin avatar Sep 16 '25 16:09 vladshcherbin

I will probably change it to oneOf but I have to check a few details before doing it. I plan to release it with v1.4 of our JSON Schema package.

fabian-hiller avatar Sep 17 '25 01:09 fabian-hiller