Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot use Zod .transform #416

Closed
alii opened this issue Jun 13, 2022 · 11 comments
Closed

Cannot use Zod .transform #416

alii opened this issue Jun 13, 2022 · 11 comments

Comments

@alii
Copy link

alii commented Jun 13, 2022

Describe the bug
Unable to use .transform with the zod resolver

To Reproduce
Use an input and see an error
image

Codesandbox link (Required)
https://codesandbox.io/s/react-hook-form-zod-resolver-example-forked-khj93c?file=/src/App.tsx

Expected behavior
The transform happens as expected, and errors thrown during transformation are treated as form errors

Desktop (please complete the following information):

  • OS: MacOS 13 Ventura
  • Browser: Chrome 102.0.5005.61 (Official Build) (arm64)

Additional context
Replaces #415 (Error carried forward)

@bluebill1049
Copy link
Member

Screen Shot 2022-06-15 at 12 45 35 pm

This is the error log that I am getting.

@bluebill1049
Copy link
Member

any update on this issue? as you can see in the console the error occurred at the zod, which indicates to me the schema could be invalid.

@alii
Copy link
Author

alii commented Jun 17, 2022

I'll see if I can put together a reproduction repo later after the weekend and get back to you. Thanks :)

@Lykan9999
Copy link

Screen Shot 2022-06-15 at 12 45 35 pm

This is the error log that I am getting.

I am getting this error when using preprocess in the zod schema. easiest solution (not optimal) was to drop its usage

@jorisre
Copy link
Member

jorisre commented Sep 12, 2022

Please open a new issue thank you

@alexgleason
Copy link

Same issue here. This does not work:

const fileListSchema = z.custom<FileList>((val) => val instanceof FileList);

const schema = z.object({
  avatar: fileListSchema.transform((fileList) => fileList.item(0)), // This does not work
});

const { register, handleSubmit, getValues, formState } = useForm<z.infer<typeof schema>>({
  resolver: zodResolver(schema),
});

avatar comes back as a FileList even though the schema transforms it into a File

@jorisre
Copy link
Member

jorisre commented Mar 30, 2023

@alexgleason Please open a new issue

@joaopedrodcf
Copy link

@alexgleason @jorisre

I think I found a solution by looking into the useForm generics definition:

As we can see we have three generics being passed:
image

const fileListSchema = z.custom<FileList>((val) => val instanceof FileList);

const schema = z.object({
  avatar: fileListSchema.transform((fileList) => fileList.item(0)), // This does not work
});

const { register, handleSubmit, getValues, formState } = useForm<z.input<typeof schema>, object, z.output<typeof schema>>({
  resolver: zodResolver(schema),
});

Basically you can defined input, context and output as the generics

Docs of zod: https://zod.dev/?id=type-inference
TLDR: z.output is equal to z.infer

This way when you defined defautValues with these generics you get the type before transform and when you call handleSubmit it will be after transform.

Hopefully this helps others.

@LeonardBoedi
Copy link

@joaopedrodcf

You just saved me a lot of pain. Thank you!

@kainbryanjones
Copy link

@alexgleason @jorisre

I think I found a solution by looking into the useForm generics definition:

As we can see we have three generics being passed: image

const fileListSchema = z.custom((val) => val instanceof FileList);

const schema = z.object({
avatar: fileListSchema.transform((fileList) => fileList.item(0)), // This does not work
});

const { register, handleSubmit, getValues, formState } = useForm<z.input, object, z.output>({
resolver: zodResolver(schema),
});
Basically you can defined input, context and output as the generics

Docs of zod: https://zod.dev/?id=type-inference TLDR: z.output is equal to z.infer

This way when you defined defautValues with these generics you get the type before transform and when you call handleSubmit it will be after transform.

Hopefully this helps others.

I am doing this but getting an TS error. I can see in the types for useForm that the TTransformedValues generic type is never passed to the UseFormProps, thus the type is giving my this error. What to do here? It wants the output to be the same as the input.

Image

@jorisre
Copy link
Member

jorisre commented Mar 27, 2025

@kainbryanjones There is an ongoing PR #753 to fix this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants