Introducing Zod 4 beta
Спустя несколько лет с выхода Zod v3 выпустили бетку Zod v4. Zod - библиотека для валидации объектов на мэтч с переданной схемой.
В 4-м релизе увеличили скорость работы валидации и работы TS по валидации типов, уменьшили размер бандла, добавили новые удобные API. Если вы используете Zod - рекомендую запланировать обновление.
Что интересного уже есть в бетке
Ускорение
- В 2.6 раз быстрее парсинг строк
- в 3 раза быстрее парсинг массивов
- в 8 раз быстрее парсинг объектов
- в 20 раз ускорение инициализации typescript на типах Zod
- в 2 раза уменьшили бандл сайз
- Если вам этого мало - сделали @zod/mini, который содержит основной функционал и весит в 6.6 раз меньше
Улучшили работу со схемами:
Сделали отдельную систему для описания метаданных к схемам
import * as z from "zod";
const myRegistry = z.registry<{ title: string; description: string }>();
const emailSchema = z.string().email();
myRegistry.add(emailSchema, { title: "Email address", description: "..." });
myRegistry.get(emailSchema);
// => { title: "Email address", ... }
Сделали вывод JSON-схемы
import * as z from "zod";
const mySchema = z.object({name: z.string(), points: z.number()});
z.toJSONSchema(mySchema);
// => {
// type: "object",
// properties: {
// name: {type: "string"},
// points: {type: "number"},
// },
// required: ["name", "points"],
// }
Сделали новое API для корректного получения типа объекта. В посте упоминают кейс, когда у одной схемы поле - опциональное (можно не указать), а другой - обязательное, но значение может быть undefined. Т.е. грубо говоря
type Obj1 = {
prop?: string;
}
type Obj2 = {
prop: string | undefined;
}
Разница небольшая, но она есть. В Zod3 нельзя получить корректный тип для этих объектов.
z.object({ name: z.string().optional() });
// { name?: string | undefined }
z.object({ name: z.union([z.string(), z.undefined()]) });
// { name?: string | undefined }
В Zod4 добавили новый метод, который это умеет, но опциональность ключа там указывается в имени ключа (что, конечно, странно. В друг у нас действительно поле со знаком в конце, что тогда делать?)
const ValueOptional = z.interface({ name: z.string().optional()});
// { name: string | undefined }
const KeyOptional = z.interface({ "name?": z.string() });
// { name?: string }
Кроме того, z.interface позволяет описывать цикличные типы проще, чем это было в Zod3
import * as z from "zod"; // zod@4
const Category = z.interface({
name: z.string(),
get subcategories() {
return z.array(Category)
}
});
Обработка ошибок
Во первых, добавили возможность указать локаль для вывода ошибок
import * as z from "zod";
// configure English locale (default)
z.config(z.locales.en());
Во вторых, улучшили форматирование ошибок
✖ Unrecognized key: "extraField"
✖ Invalid input: expected string, received number
→ at username
✖ Invalid input: expected number, received string
→ at favoriteNumbers[1]
В общем, интересный большой апдейт для важной библиотеки.
https://v4.zod.dev/v4
#development #javascript #library #zod #release