I have a form which use React Hook Form and Zod as validator.
I have to validate some fields if the Committente
type is Privato
and some others if is Azienda
(Let's just ignore Azienda Estera
)
For Privato
type I have those fields:
while for Azienda
those others:
So, basically, the fields Nome
, Cognome
, and Codice Fiscale
are undefined when azienda
is selected and the fields Nome Azienda
and Partita Iva
are undefined when privato
is selected.
How can I build this type of schema?
I tried something like this:
const mySchema = z.union([
z.object({
tipologia: z.literal("privato"),
nome: z.string().min(1, { message: "Il nome è richiesto" }),
cognome: z.string().min(1, { message: "Il cognome è richiesto" }),
...
}),
z.object({
tipologia: z.literal("azienda"),
nomeAzienda: z.string().min(5, { message: "Il nome è richiesto" }),
...
}),
])
but didn't work.
I made it works using discriminatedUnion
method. Actually, while testing, I was just forgetting to implement the invalid
and error
message on the fields, so I didn't have any feedbacks and I thought it doesn't work.
// Base Schema
const baseSchema = z.object({
indirizzo: z.string().min(3, { message: "L'indirizzo è richiesto" }),
cap: z
.string()
...
})
// Schema
const mySchema = z.discriminatedUnion("tipologia", [
z
.object({
tipologia: z.literal("privato"),
nome: z.string().min(1, { message: "Il nome è richiesto" }),
cognome: z.string().min(1, { message: "Il cognome è richiesto" }),
cf: z.string().min(16, { message: "Il Codice Fiscale è richiesto" }),
stato: z.literal("Italia"),
})
.merge(baseSchema),
z
.object({
tipologia: z.literal("azienda"),
nomeAzienda: z.string().min(1, { message: "Il nome è richiesto" }),
piva: z.string().min(11, { message: "La Partita IVA è richiesta" }),
stato: z.literal("Italia"),
})
.merge(baseSchema),
z
.object({
tipologia: z.literal("aziendaEstera"),
nomeAzienda: z.string().min(1, { message: "Il nome è richiesto" }),
piva: z.string().min(11, { message: "La Partita IVA è richiesta" }),
stato: z.string().min(1, { message: "Indicare lo Stato" }),
})
.merge(baseSchema),
]),