Zod discriminatedUnion

Hi guys, I have na union type as follows:
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(),
})
),
}),
])
),
I want to get typesafe value from form to properly map questions. Currently I've done this:

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;
};
But i still get an error 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
Patryk Makowski
Patryk MakowskiOP2y ago
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
)}
/>
);
})}
Want results from more Discord servers?
Add your server