Discriminated union of another discriminated union #2180
-
Consider this use case where I have a requirement to make a validation schema for a complex form. User can either choose to fill the details of the form manually or upload a csv instead of filling the form. import { z } from "zod";
const SolarEnergySchema = z.object({
type: z.literal("Solar"),
solarField1: z.string(),
solarField2: z.string(),
uploadCsv: z.literal(false)
});
const WindEnergySchema = z.object({
type: z.literal("Wind"),
windField1: z.string(),
windField2: z.string(),
uploadCsv: z.literal(false)
});
const WaterEnergySchema = z.object({
type: z.literal("Water"),
waterField1: z.string(),
waterField2: z.string(),
uploadCsv: z.literal(false)
});
const EnergyUnionSchema = z.discriminatedUnion("type", [
SolarEnergySchema,
WindEnergySchema,
WaterEnergySchema
]);
const CSVSchema = z.object({
uploadCsv: z.literal(true),
csvFile: z.instanceof(File)
});
// Form Fields can be either of type EnergyUnionSchema or CSVSchema
const FormSchema = z.discriminatedUnion("uploadCsv", [
EnergyUnionSchema, // type error
CSVSchema
]); The form itself is complex and has dependent fields based on a Sandbox link: https://codesandbox.io/s/weathered-darkness-6okw7n?file=/src/index.ts I have tried using union instead of discriminated union but that doesn't work for my use case because I have using react-hook-form with zod as resolver. If I mark |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
Everything seems to be working fine when I use const SolarEnergySchema = z.object( {
type: z.literal( 'Solar' ),
solarField1: z.string(),
solarField2: z.string(),
uploadCsv: z.literal( false )
} )
const WindEnergySchema = z.object( {
type: z.literal( 'Wind' ),
windField1: z.string(),
windField2: z.string(),
uploadCsv: z.literal( false )
} )
const WaterEnergySchema = z.object( {
type: z.literal( 'Water' ),
waterField1: z.string(),
waterField2: z.string(),
uploadCsv: z.literal( false )
} )
const EnergyUnionSchema = z.discriminatedUnion( 'type', [
SolarEnergySchema,
WindEnergySchema,
WaterEnergySchema
] )
const CSVSchema = z.object( {
uploadCsv: z.literal( true ),
csvFile: z.instanceof( File )
} )
const FormSchema = z.union( [
EnergyUnionSchema,
CSVSchema
] )
console.log(
FormSchema.parse( {
type: 'Solar',
solarField1: 'solarField1',
solarField2: 'solarField2',
uploadCsv: false
} ),
)
// {
// type: 'Solar',
// solarField1: 'solarField1',
// solarField2: 'solarField2',
// uploadCsv: false
// } Perhaps you can post a codesandbox with the react-hook-form code also? |
Beta Was this translation helpful? Give feedback.
-
Yes, I did some more research and it is indeed an issue with react-hook-form. The error object I get from the hook contains errors for all fields in the form and I guess that's just how the zod resolver for hook form works. I will probably have to add custom logic to ignore the other error messages when |
Beta Was this translation helpful? Give feedback.
Everything seems to be working fine when I use
z.union
. Seems like a problem with react-hook-form zod resolver.