colinhacks / zod

TypeScript-first schema validation with static type inference
https://zod.dev
MIT License
31.77k stars 1.1k forks source link

How to validate FormData object? #3333

Open da1z opened 3 months ago

da1z commented 3 months ago

is there proper way to validate FormData type without it converting to object?

colinhacks commented 3 months ago

Not really. You can do z.instanceof(FormData) but that's about it. I've considered a z.formdata() API that would let you specify whether to .get() or .getAll() each field. Then you're left with {[k: string]: string | string[] }, and you'd have to use .transform() to do any additional coercion/transforms. Ultimately I wasn't sure it was worthwhile, but feel free to propose an API here.

LiamMartens commented 2 months ago

I don't think this is useful since FormData objects are rarely validated like this imo. Coming into express they are just objects and when using forms in react or otherwise they are also generally stored as objects. So FormData is just a an object for transportation.

da1z commented 2 months ago

I don't think this is useful since FormData objects are rarely validated like this imo. Coming into express they are just objects and when using forms in react or otherwise they are also generally stored as objects. So FormData is just a an object for transportation.

I would not say it is useless since form server action in next js receives FormData as parameter and it would be very useful to validate formdata with zod before processing it.

export default function Page() {
  async function createInvoice(formData: FormData) {
    'use server'

    const rawFormData = {
      customerId: formData.get('customerId'),
      amount: formData.get('amount'),
      status: formData.get('status'),
    }

    // mutate data
    // revalidate cache
  }

  return <form action={createInvoice}>...</form>
}
LiamMartens commented 2 months ago

@da1z ah my bad! I didn't realize that's how next handled it 🤔 I wonder what this API would look like...

da1z commented 2 months ago

@da1z ah my bad! I didn't realize that's how next handled it 🤔 I wonder what this API would look like...

i would prefer to keep existing api but make it compatible with formData object so I can use it like this:

const schema = z.object({
  name: z.string(),
});
const parsed: z.infer<typeof schema> = schema.parse(formData);