colinhacks / zod

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

If object with nested refine fails, it doesn't apply transform before superRefine, causing superRefine to not be typesafe #3573

Open matowang opened 5 months ago

matowang commented 5 months ago

Object with nested define doesn't apply transform before superRefine, causing superRefine to not be typesafe.

  const res = z
    .object({
      name: z.string(),
      age: z.number().refine((data) => {
        return data > 18;
      }), // Fails refine
    })
    .transform((data) => {
      return {
        userName: data.name,
        userAge: data.age,
      };
    })
    .superRefine((data) => {
      // Data here is { "name": "John", "age": 6 }, Expected { "userName": "John", "userAge":  6} after transformation
      console.log("superRefine", JSON.stringify(data, null, 2));
    })
    .safeParse({
      name: "John",
      age: 6,
    });
  console.log(res);

This parsing should abort early or perform the transformation anyway. Transform isn't applied here.

Torsten85 commented 3 months ago

I think my issue is the same (or very related). Chaining .transform with .superRefine skips transform when the input is invalid.

this here:

 const uuidSchema = z
    .string()
    .uuid()
    .transform((value) => {
      console.log('transform called')
      return value
    })
    .superRefine(() => {
      console.log('super refine called')
    })

  uuidSchema.parse('invalid')

logs super refine called but not(!) transform called. Is this a bug or by design? How could I check if transform did successfully in super refine?