Skip to content

Releases: colinhacks/zod

v3.9.8

05 Oct 19:51
Compare
Choose a tag to compare

v3.9.8

v3.9.0

25 Sep 22:25
Compare
Choose a tag to compare

✨ Zod 3.9 ✨

Custom error messages in schemas

const name = z.string({
  invalid_type_error: "Name must be string",
  required_error: "Name is required",
});

Under the hood, this creates a custom error map that's bound to the schema. You can also pass a custom error map explicitly.

const name = z.string({ errorMap: myErrorMap });

Rest parameters for tuples

const myTuple = z.tuple([z.string(), z.number()]).rest(z.boolean());
type t1 = z.output<typeof myTuple>; // [string, number, ...boolean[]]

Selective .partial

You can specify certain fields to make optional with the ZodObject.partial method.

const user = z.object({
  name: z.string(),
  age: z.number(),
});

const optionalNameUser = user.partial({ name: true });
// { name?: string; age: number; }

Support key schema in ZodRecord

Previously, z.record only accepted a single schema:

z.record(z.boolean()); // Record<string, boolean>;

Now z.record has been overloaded to support two schemas. The first validates the keys of the record, and the second validates the values.

const schema = z.record(z.number(), z.boolean());
type schema = z.infer<typeof schema>; // Record<number, boolean>

const schema = z.record(z.enum(["Tuna", "Trout"]), z.boolean());
type schema = z.infer<typeof schema>; // Record<"Tuna" | "Trout", boolean>

Don't short-circuit on some validation errors

Certain issue types "short circuit" the rest of the validation logic. If you pass a number into a ZodString schema, Zod throws an error immediately, without passing the input through any downstream refinements or transforms. This is intentional; those refinements/transforms are likely to throw unexpected errors since they assume a number input.

However other kinds of errors shouldn't "short circuit" like this. For instance z.string().min(10).email(). If we try to parse "asdf" with this schema, we should get two errors: "Invalid email" and "Input should contain at least 10 characters". If we short circuit after the "min" error, then Zod fails to surface the full set of validation issues.

Zod now considers certain classes of validation errors "continuable", in that they don't short circuit validation logic. This makes Zod more usable in form validation settings like this:

const user = z
  .object({
    password: z.string().min(6),
    confirm: z.string(),
  })
  .refine((data) => data.password === data.confirm, "Passwords don't match");
const result = user.safeParse({ password: "asdf", confirm: "qwer" });

This will return an error with two issues. Previously the parsing would have short-circuited after the inner password was invalid.

/*
ZodError: [
    {
      "code": "too_small",
      "minimum": 6,
      "type": "string",
      "inclusive": true,
      "message": "Should be at least 6 characters",
      "path": [ "password" ]
    },
    {
      "code": "custom",
      "message": "Passwords don't match",
      "path": [ "confirm" ]
    }
  ]
*/

v3.8.0

23 Aug 03:36
7fe864e
Compare
Choose a tag to compare

Release: [email protected]
What's new:

z.preprocess

This lets you transform input data before it is parsed by your schema. This is useful for several use cases, notably type coercion. Usage:

const coercedString = z.preprocess(
  val => String(val),
  z.string()
)
mySchema.parse(12); // => "12"
mySchema.parse(true); // => "true"

CUID validation

Courtesy of @alii

const cuid = z.string().cuid()
cuid.parse("ckopqwooh000001la8mbi2im9");

Improved .deepPartial()

The .deepPartial() method on object schemas now recursively traverses through ZodArray, ZodTuple, ZodOptional, and ZodNullable elements. Previously, this method only worked in hierarchies of simple object schemas.

const mySchema = z.object({
  name: z.string(),
  array: z.array(z.object({ asdf: z.string() })),
  tuple: z.tuple([
    z.object({ value: z.string() })
  ]),
}) 

const partialed = mySchema.deepPartial();
type partialed = z.infer<typeof partialed>;
/*
  {
    name?: string | undefined;
    array?: {
        asdf?: string | undefined;
    }[] | undefined;
    tuple?: [{value?: string}] | undefined;
  }
*/

v3.7.3

19 Aug 17:25
Compare
Choose a tag to compare

Improve Zod stack traces

v3.7.0

01 Aug 23:23
Compare
Choose a tag to compare
  • Eliminate ZodNonEmptyArray, add Cardinality to ZodArray
  • Add optional error message to ZodArray.nonempty
  • Add .gt/.gte/.lt/.lte to ZodNumber, alias min -> gte and max -> lte

v3.6.1

01 Aug 03:22
Compare
Choose a tag to compare
  • Add IE11 support

  • ZodError.flatten now optionally accepts a map function for customizing the output

  • .void() now only accepts undefined, not null.

  • z.enum now supports Readonly string tuples

    const HTTP_SUCCESS = ["200", "201"] as const;
    const arg = z.enum(HTTP_SUCCESS);
    

v3.5.1

14 Jul 17:32
9eb7eb1
Compare
Choose a tag to compare
Merge pull request #527 from andersk/readme-fragments

README: Fix broken fragment links

v3.5.0

06 Jul 21:56
Compare
Choose a tag to compare

3.5

  • Add discriminator to all first-party schema defs

v3.4.2

06 Jul 16:25
Compare
Choose a tag to compare

Bug fixes.

v3.4.0

06 Jul 16:01
Compare
Choose a tag to compare

3.4

  • unknown and any schemas are always interpreted as optional. Reverts change from 3.3.

3.3.0

  • HUGE speed improvements
  • Added benchmarking: yarn benchmark
  • Type signature of ZodType#_parse has changed. This will affects users who have implemented custom subclasses of ZodType.
  • [reverted] Object fields of type unknown are no longer inferred as optional.