Zod Info

These are useful zod snippets

Optional vs Nullable vs Nullish

// zod schema
z.object({
    // valid if string or:
    optional: z.string().optional(), // field not provided, or explicitly `undefined`
    nullable: z.string().nullable(), // field explicitly `null`
    nullish: z.string().nullish(), // field not provided, explicitly `null`, or explicitly `undefined`
});
 
// type
{
    optional?: string | undefined;
    nullable: string | null;
    nullish?: string | null | undefined;
}

Async zod refinements

const userId = z.string().refine(async (id) => {
  // verify that ID exists in database
  return true;
});

⚠️ If you use async refinements, you must use the .parseAsync method to parse data! Otherwise Zod will throw an error.

.transform

To transform data after parsing, use the transform method.

const stringToNumber = z.string().transform((val) => val.length);
 
stringToNumber.parse("string"); // => 6

Email fails parsing on blank string

'' is not a valid email address, so we need to .union with a literal ''

const emailSchema = z.union([z.literal(""), z.email()]);
console.log(emailSchema.safeParse("").success); // true
console.log(emailSchema.safeParse("[email protected]").success); // true
console.log(emailSchema.safeParse("foo").success); // false

Codecs

All Zod schemas can process inputs in both the forward and backward direction:

In my usage, Output is the database, Input is the form

  • Forward: Input to Output (going from the form to the database)
    • .parse()
    • .decode()
  • Backward: Output to Input (going from the database to the form)
    • .encode()