fabian-hiller / valibot

The modular and type safe schema library for validating structural data 🤖
https://valibot.dev
MIT License
5.88k stars 181 forks source link

Empty object type returned by flattening a Variant Schema #700

Closed ShlokDesai33 closed 2 months ago

ShlokDesai33 commented 2 months ago

When I try to safe parse with a Variant schema, the nested issues have type = {} | undefined. Here's an example:

const VariantSchema = v.variant('type', [
    v.object({
        type: v.literal('email'),
        email: v.pipe(v.string(), v.email()),
    }),
    v.object({
        type: v.literal('url'),
        url: v.pipe(v.string(), v.url()),
    }),
    v.object({
        type: v.literal('date'),
        date: v.pipe(v.string(), v.isoDate()),
    }),
]);

const { success, issues } = v.safeParse(VariantSchema, { hi: 'hello ' });

if (!success) {
    const { nested, root } = v.flatten<typeof VariantSchema>(issues);
}

Is there a fix / workaround to this issue?

fabian-hiller commented 2 months ago

Yes, this is a known issue that will be fixed in the future. Currently there is a circular dependency that I need to investigate. See the code here.

The simplest workaround for now is to simply not pass a generic to flatten. Sorry for the inconvenience.

const { nested, root } = v.flatten(issues);
ShlokDesai33 commented 2 months ago

You don't need to apologize, this library is the best validation tool out there! Thank you for the workaround!

I think a better solution to this problem would be to use a union of objects instead. This returns the correct types for both the output and errors. But I'm seeing weird behavior. When I switch the variant schema to a union of objects, the nested errors is undefined and the root error = 'Invalid type: Expected Object but received Object'. Is this expected behavior?

fabian-hiller commented 2 months ago

When I switch the variant schema to a union of objects, the nested errors is undefined

In my case they are optional undefined because we have no guarantee that every path has an issue. Please take a look at this playground and let me know if it looks good.

[...] the root error = 'Invalid type: Expected Object but received Object'

I do not have a better solution for this at the moment. This is a rare case, as you would normally use variant for objects.

ShlokDesai33 commented 2 months ago

The example provided in the playground is exactly the behavior I was looking for! Closing this issue for now since I have implemented the work around you provided. Thank you for the help!

fabian-hiller commented 1 week ago

This is fixed in v0.39.0