Skip to content

Make fallback optionally get nested fallbacks recursively #1173

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

Open
SarcevicAntonio opened this issue Apr 28, 2025 · 2 comments
Open

Make fallback optionally get nested fallbacks recursively #1173

SarcevicAntonio opened this issue Apr 28, 2025 · 2 comments
Assignees
Labels
question Further information is requested

Comments

@SarcevicAntonio
Copy link

In zod defining a .default({}) on a z.object whose properties has default values itself will recursively get the nested default values and merge them into the top level default value:

const Schema = z.object({
  name: z.string().default(''),
}).default({})

console.log(schema.parse(undefined))
// { name : "test"} ✅

Valibot however just simply takes the top level fallback value, and ignores the rest of the fallback values:

const Schema = v.fallback(v.object({
  name: v.fallback(v.string(), "test"),
}), {} as any)

console.log(v.parse(Schema, undefined))
// {} 😢

I already know about getFallbacks which I could use to get the same behaviour, but requires an extra step of defining the top level object first without fallback and then adding it with the getFallbacks function call for the fallback value:

const RawSchema = v.object({
  name: v.fallback(v.string(), "test"),
})

const Schema = v.fallback(RawSchema, v.getFallbacks(RawSchema))

console.log(v.parse(Schema, undefined));
// { name : "test"} ✅

Now this isn't a huge hassle, but still a slight inconvenience compared to zod's default implementation 👀

Would it maybe be possible to somehow make the fallback function recursively get the nested fallback values as well, like zod's default does? I am aware that this might not be desirable for some cases, so it should be behind an option of sort, or maybe be a different function entirely? Maybe I'm also missing something that already does this in a simpler way, or maybe this isn't possible due to the modular nature of the project. Anyhow, I thought I'd share this to open a discussion. Thanks for reading!

@muningis
Copy link
Contributor

It's coming in 2.0.0 #1155

@fabian-hiller
Copy link
Owner

Thank you for creating this issue! I think our implementation is similar or equal to Zod's. Quick note: .default in Zod is not the same as v.fallback in Valibot. Instead you should use v.optional or one of the other schemes to define defaults. Here is the updated code. Feel free to try it out in our playground.

import * as v from 'valibot';

const Schema = v.optional(
  v.object({
    name: v.optional(v.string(), ''),
  }),
  {},
);

@fabian-hiller fabian-hiller self-assigned this Apr 29, 2025
@fabian-hiller fabian-hiller added the question Further information is requested label Apr 29, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

3 participants