Zod discriminatedUnion
Hi guys, I have na union type as follows:
I want to get typesafe value from form to properly map questions.
Currently I've done this:
But i still get an error
ts
sections: z.array(
z.discriminatedUnion("sectionType", [
z.object({
sectionType: z.literal("single"),
sectionName: z.string(),
answer: z.string(),
}),
z.object({
sectionType: z.literal("multiple"),
sectionName: z.string(),
questions: z.array(
z.object({
question: z.string(),
answer: z.string(),
})
),
}),
])
),
ts
sections: z.array(
z.discriminatedUnion("sectionType", [
z.object({
sectionType: z.literal("single"),
sectionName: z.string(),
answer: z.string(),
}),
z.object({
sectionType: z.literal("multiple"),
sectionName: z.string(),
questions: z.array(
z.object({
question: z.string(),
answer: z.string(),
})
),
}),
])
),
export const getSection = <T extends SelfFormValues["sections"][number]>(
section: T | undefined,
type: T["sectionType"]
) => {
if (!section) throw new Error("Section not found");
if (section.sectionType !== type) throw new Error("Section type mismatch");
return section;
};
export const getSection = <T extends SelfFormValues["sections"][number]>(
section: T | undefined,
type: T["sectionType"]
) => {
if (!section) throw new Error("Section not found");
if (section.sectionType !== type) throw new Error("Section type mismatch");
return section;
};
Property 'questions' does not exist on type '{ answer: string; sectionType: "single"; sectionName: string; }
when used like this:
{getSection(values.sections[0], "multiple")?.questions.map(
({ question }, index) => {
if (!question) return null;
const [label, subText] = question.replace(")", "").split("(");
return (
<SingleOptionRadio
isVertical
key={question}
label={`${label}`}
subText={subText}
{...getInputProps(
`sections.0.answers.${index}.answer` as const
)}
/>
);
}
)}
{getSection(values.sections[0], "multiple")?.questions.map(
({ question }, index) => {
if (!question) return null;
const [label, subText] = question.replace(")", "").split("(");
return (
<SingleOptionRadio
isVertical
key={question}
label={`${label}`}
subText={subText}
{...getInputProps(
`sections.0.answers.${index}.answer` as const
)}
/>
);
}
)}
1 Reply
Is this the only solution?
{values.sections[0]?.sectionType === "multiple" &&
values.sections[0].questions.map(({ question }, index) => {
if (!question) return null;
const [label, subText] = question.replace(")", "").split("(");
return (
<SingleOptionRadio
isVertical
key={question}
label={`${label}`}
subText={subText}
{...getInputProps(
`sections.0.answers.${index}.answer` as const
)}
/>
);
})}
{values.sections[0]?.sectionType === "multiple" &&
values.sections[0].questions.map(({ question }, index) => {
if (!question) return null;
const [label, subText] = question.replace(")", "").split("(");
return (
<SingleOptionRadio
isVertical
key={question}
label={`${label}`}
subText={subText}
{...getInputProps(
`sections.0.answers.${index}.answer` as const
)}
/>
);
})}