T
TanStack5mo ago
deep-jade

Different schema for form and output

Is there a way to specify two different schemas, one for the form state and one for the output upon submission? For example the form schema would be:
// type or using zod
type FormSchema = {
name: string;
timezone: Timezone | null; // populated via select
}
// type or using zod
type FormSchema = {
name: string;
timezone: Timezone | null; // populated via select
}
while the output schema would be:
type OutputSchema = {
name: string;
timezone: Timezone; // notice that this must be set once the form is submitted
}
type OutputSchema = {
name: string;
timezone: Timezone; // notice that this must be set once the form is submitted
}
FormSchema would be used within the form (e.g. showing a preview of what the timezone settings are when a timezone is selected or not) while OutputSchema would only be used upon submission and validation.
4 Replies
mere-teal
mere-teal5mo ago
The form works with the Input Schema, for Zod thats z.input(typeof yourSchema) you can also get the Output Schema using z.output(typeof yourSchema)
const form = useForm({
defaultValues: {
// your fields
} as z.input(typeof yourSchema),
validators: {
onSubmit: yourSchema
},
onSubmit: ({ value }) => {
// the `value` here is of the z.input type

const parsed = yourSchema.safeParse(value)

if (!parsed.success) throw "Could not parse"

console.log(parsed.data) // <-- `data` is of z.output type
},
})
const form = useForm({
defaultValues: {
// your fields
} as z.input(typeof yourSchema),
validators: {
onSubmit: yourSchema
},
onSubmit: ({ value }) => {
// the `value` here is of the z.input type

const parsed = yourSchema.safeParse(value)

if (!parsed.success) throw "Could not parse"

console.log(parsed.data) // <-- `data` is of z.output type
},
})
deep-jade
deep-jadeOP5mo ago
I see. Weird, I would expect value in onSubmit to be already validated based on validators
afraid-scarlet
afraid-scarlet5mo ago
but field schemas could take precedence and have different outputs so it would still be unintuitive. As for now, it voids the transformed output
deep-jade
deep-jadeOP5mo ago
I see, thanks all ❤️

Did you find this page helpful?