Replies: 3 comments 5 replies
-
+1 here.
const schema = z.object({
amount: z.number().nullable().transform((v) => v ?? 0)
});
type FormFields = z.input<typeof schema>;
// { amount: number | null | undefined }
type FormPayload = z.output<typeof schema>;
// { amount: number }
const form = useForm<FormFields, FormPayload>({
resolver: zodResolver(schema),
});
const handleSubmit = form.handleSubmit(
function onValid (payload) {
// { amount: number }
}
); At present, the only resolution I know of (as @Svish suggests) is to hard-assert it in the submit handler.... const handleSubmit = form.handleSubmit(
function onValid (values) {
const payload = values as unknown as FormPayload;
// { amount: number }
}
); |
Beta Was this translation helpful? Give feedback.
-
Also just a hack, but maybe helpful for someone. I took another approach: Instead of allowing Here's a small helper to make one or more fields of your schema export type OmitStrict<T, K extends keyof T> = T extends unknown
? Pick<T, Exclude<keyof T, K>>
: never
export type Undefinable<T> = T | undefined
/**
* This is a hack for a schema that needs an `undefined` field on the input which is not allowed to be `undefined` for the output.
* This situation e.g. exists on fields of an initial form to create something. e.g. we don't want to have a category selected when
* a new post is created, so the field is `undefined`.
*/
export type FormDefaultValuesUndefinable<
TSchema extends z.ZodTypeAny['_output'],
TKeyToOverwrite extends keyof TSchema
> = OmitStrict<TSchema, TKeyToOverwrite> & {
[K in keyof TSchema as TKeyToOverwrite]: Undefinable<TSchema[TKeyToOverwrite]>
} In this example I expect a type SchemaCreatePost = z.infer<typeof schemaCreatePost>
const defaultValuesCreate: FormDefaultValuesUndefinable<
SchemaCreatePost,
'categoryId'
> = { title: '', categoryId: undefined } |
Beta Was this translation helpful? Give feedback.
-
To answer your original question. You can do this now: const { handleSubmit } = useForm<InputType, unknown, OutputTypeAfterValidation>({
// ...
}) |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Take the following schema written using
yup
:I now want to use these types with
useForm
:The issue is that I have to substitute
???
for eitherYupValues
orYupValid
. Picking the first allows me to set the default value tonull
, but gives me the wrong type in my submit-handler. Picking the second gives me the correct data type in my submit-handler, but doesn't allow me to usenull
as a default value...Is there a way to do this correctly typewise? I assume the type being passed into the submit-handler will have been through the yup resolver and therefore will be valid and match the
YupValid
type, so I suppose I could "cast" it with anas YupValid
, but I really don't like usingas
if I can avoid it.There's a similar concept with
zod
, which is actually calledinput
andoutput
:Here it would similarly be great if there was a way to get the correct type in the correct places when using
react-hook-form
.Beta Was this translation helpful? Give feedback.
All reactions