new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Zod · all subjects

schema definition

37 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Defining a basic object schema

To define a schema in Zod, import the library and use z.object() with field definitions. For example: const Player = z.object({ username: z.string(), xp: z.number() });

z.codec() defines bidirectional transformation

z.codec() creates a schema that defines a bidirectional transformation between two other schemas. It takes three arguments: an input schema, an output schema, and an object with decode and encode transform functions.

Codec example: ISO string to Date transformation

const stringToDate = z.codec(z.iso.datetime(), z.date(), { decode: (isoString) => new Date(isoString), encode: (date) => date.toISOString() }); stringToDate.decode("2024-01-15T10:30:00.000Z") returns a Date object; stringToDate.encode(new Date("2024-01-15T10:30:00.000Z")) returns a string.

z.invertCodec() reverses a codec

z.invertCodec() derives the reverse codec from an existing one by swapping the input and output schemas, then swapping the decode and encode transforms. It only inverts the codec passed to it and does not recursively invert nested codecs.

Codecs are composable like any schema

Codecs can be nested inside objects, arrays, pipes, and anywhere else a regular schema can be used. They follow the same composability rules as other Zod schemas.

Codecs implemented as pipe subclasses

Codecs are implemented internally as subclasses of pipes with interstitial transform logic. During decoding, a ZodPipe<A, B> first parses with A then passes to B. During encoding, data is first encoded with B then passed into A.

Defaults and prefaults only apply in forward direction

Defaults and prefaults are only applied during decoding (forward direction). During encoding, undefined is not a valid input and defaults will not be applied. z.string().default("hello").encode(undefined) throws ZodError: Expected string, received undefined.

.catch() only applies in forward direction

.catch() is only applied during decoding (forward direction). During encoding, invalid values throw ZodError instead of being caught. z.string().catch("hello").encode(1234) throws ZodError: Expected string, received number.

z.stringbool() codec

z.stringbool() converts string values ("true", "false", "yes", "no", etc.) into boolean during decode. During encode, by default it converts true to "true" and false to "false". With custom truthy/falsy values like z.stringbool({ truthy: ["yes", "y"], falsy: ["no", "n"] }), the first element in each array is used during encode.

stringToNumber codec implementation

const stringToNumber = z.codec(z.string().regex(z.regexes.number), z.number(), { decode: (str) => Number.parseFloat(str), encode: (num) => num.toString() }); stringToNumber.decode("42.5") returns 42.5; stringToNumber.encode(42.5) returns "42.5".

stringToInt codec implementation

const stringToInt = z.codec(z.string().regex(z.regexes.integer), z.int(), { decode: (str) => Number.parseInt(str, 10), encode: (num) => num.toString() }); stringToInt.decode("42") returns 42; stringToInt.encode(42) returns "42".

stringToBigInt codec implementation

const stringToBigInt = z.codec(z.string(), z.bigint(), { decode: (str) => BigInt(str), encode: (bigint) => bigint.toString() }); stringToBigInt.decode("12345") returns 12345n; stringToBigInt.encode(12345n) returns "12345".

numberToBigInt codec implementation

const numberToBigInt = z.codec(z.int(), z.bigint(), { decode: (num) => BigInt(num), encode: (bigint) => Number(bigint) }); numberToBigInt.decode(42) returns 42n; numberToBigInt.encode(42n) returns 42.

isoDatetimeToDate codec implementation

const isoDatetimeToDate = z.codec(z.iso.datetime(), z.date(), { decode: (isoString) => new Date(isoString), encode: (date) => date.toISOString() }); isoDatetimeToDate.decode("2024-01-15T10:30:00.000Z") returns Date object; isoDatetimeToDate.encode(new Date("2024-01-15")) returns "2024-01-15T00:00:00.000Z".

epochSecondsToDate codec implementation

const epochSecondsToDate = z.codec(z.int().min(0), z.date(), { decode: (seconds) => new Date(seconds * 1000), encode: (date) => Math.floor(date.getTime() / 1000) }); epochSecondsToDate.decode(1705314600) returns Date object; epochSecondsToDate.encode(new Date()) returns Unix timestamp in seconds.

epochMillisToDate codec implementation

const epochMillisToDate = z.codec(z.int().min(0), z.date(), { decode: (millis) => new Date(millis), encode: (date) => date.getTime() }); epochMillisToDate.decode(1705314600000) returns Date object; epochMillisToDate.encode(new Date()) returns Unix timestamp in milliseconds.

json(schema) generic codec implementation

const jsonCodec = <T extends z.core.$ZodType>(schema: T) => z.codec(z.string(), schema, { decode: (jsonString, ctx) => { try { return JSON.parse(jsonString); } catch (err: any) { ctx.issues.push({ code: "invalid_format", format: "json", input: jsonString, message: err.message }); return z.NEVER; } }, encode: (value) => JSON.stringify(value) }); Parses JSON strings into structured data validated by the output schema.

json codec usage example

const jsonToObject = jsonCodec(z.object({ name: z.string(), age: z.number() })); jsonToObject.decode('{"name":"Alice","age":30}') returns { name: "Alice", age: 30 }; jsonToObject.encode({ name: "Bob", age: 25 }) returns '{"name":"Bob","age":25}'.

bytesToUtf8 codec implementation

const bytesToUtf8 = z.codec(z.instanceof(Uint8Array), z.string(), { decode: (bytes) => new TextDecoder().decode(bytes), encode: (str) => new TextEncoder().encode(str) }); bytesToUtf8.decode(bytes) returns "Hello, 世界!"; bytesToUtf8.encode("Hello, 世界!") returns Uint8Array.

base64urlToBytes codec implementation

const base64urlToBytes = z.codec(z.base64url(), z.instanceof(Uint8Array), { decode: (base64urlString) => z.util.base64urlToUint8Array(base64urlString), encode: (bytes) => z.util.uint8ArrayToBase64url(bytes) }); base64urlToBytes.decode("SGVsbG8") returns Uint8Array([72, 101, 108, 108, 111]); base64urlToBytes.encode(bytes) returns "SGVsbG8".

hexToBytes codec implementation

const hexToBytes = z.codec(z.hex(), z.instanceof(Uint8Array), { decode: (hexString) => z.util.hexToUint8Array(hexString), encode: (bytes) => z.util.uint8ArrayToHex(bytes) }); hexToBytes.decode("48656c6c6f") returns Uint8Array([72, 101, 108, 108, 111]); hexToBytes.encode(bytes) returns "48656c6c6f".

stringToHttpURL codec implementation

const stringToHttpURL = z.codec(z.httpUrl(), z.instanceof(URL), { decode: (urlString) => new URL(urlString), encode: (url) => url.href }); stringToHttpURL.decode("https://api.example.com/v1") returns URL object; stringToHttpURL.encode(url) returns "https://api.example.com/v1".

uriComponent codec implementation

const uriComponent = z.codec(z.string(), z.string(), { decode: (encodedString) => decodeURIComponent(encodedString), encode: (decodedString) => encodeURIComponent(decodedString) }); uriComponent.decode("Hello%20World%21") returns "Hello World!"; uriComponent.encode("Hello World!") returns "Hello%20World!".

Zod is a TypeScript-first validation library

Zod is a TypeScript-first validation library that allows you to define schemas for validating data, from simple strings to complex nested objects.

Basic schema parsing example with User object

Example showing how to define a User schema with z.object and z.string, then parse untrusted input data using the parse method. The parsed result is validated and type-safe.

Zod core bundle size and dependencies

Zod has zero external dependencies, is 2kb when gzipped, and has an immutable API where methods return a new instance.

Zod works in Node.js and modern browsers

Zod works in Node.js and all modern browsers, with TypeScript v5.5 and later officially supported.

TypeScript strict mode required

You must enable strict mode in your tsconfig.json to use Zod. This is set via the compilerOptions strict property set to true.

Zod npm installation command

Zod is installed via npm install zod. It is also available as @zod/zod on jsr.io.

$ZodType base class for all schemas

The base class for all Zod schemas is $ZodType, which accepts two generic parameters: Output and Input. The class contains a _zod property with internals. All Zod schema classes inherit from $ZodType.

$ZodTypes union of all first-party schema classes

zod/v4/core exports a union type $ZodTypes that includes: $ZodString, $ZodNumber, $ZodBigInt, $ZodBoolean, $ZodDate, $ZodSymbol, $ZodUndefined, $ZodNull, $ZodAny, $ZodUnknown, $ZodNever, $ZodVoid, $ZodArray, $ZodObject, $ZodUnion, $ZodDiscriminatedUnion, $ZodIntersection, $ZodTuple, $ZodRecord, $ZodMap, $ZodSet, $ZodLiteral, $ZodEnum, $ZodPromise, $ZodLazy, $ZodOptional, $ZodDefault, $ZodTemplateLiteral, $ZodCustom, $ZodTransform, $ZodNonOptional, $ZodReadonly, $ZodNaN, $ZodPipe, $ZodCodec, $ZodPreprocess, $ZodSuccess, $ZodCatch, and $ZodFile.

$ZodType._zod internals structure

$ZodType instances contain a _zod property with the following notable sub-properties: .def (the schema's definition including .def.type as a string and .def.checks as an array), .input (virtual property storing inferred input type), .output (virtual property storing inferred output type), and .run() (the schema's internal parser implementation).

Extending Zod schemas - traversal pattern

To traverse Zod schemas, cast any schema to $ZodTypes and use the def property to discriminate between classes. Access schema._zod.def.type to get the schema type string (e.g. 'string', 'object', 'array') and use it in a switch statement.

ZodType base class methods overview

All schemas extend the z.ZodType base class. All instances of ZodType implement methods in these categories: parsing (parse, safeParse, parseAsync, safeParseAsync), refinements (refine, superRefine, overwrite), wrappers (optional, nonoptional, nullable, nullish, default, array, or, transform, catch, pipe, readonly), metadata and registries (register, describe, meta), and utilities (check, clone, brand, isOptional, isNullable).

Zod API design principle

Zod aims to provide a schema API that maps one-to-one to TypeScript's type system. The API relies on methods to provide a concise, chainable, autocomplete-friendly way to define complex types.

Method chaining example

Schemas support method chaining for concise, readable definitions. For example: z.string().min(5).max(10).toLowerCase() chains validation and transformation methods together.

Basic schema definition example

A basic object schema can be defined using z.object() with nested schemas for each property. Example: z.object({ name: z.string(), age: z.number().int().positive(), email: z.email() }) defines an object with string name, positive integer age, and email-formatted string email.

Give your agent this brain