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

refinements and transforms

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

$ZodCheck base class for all checks

$ZodCheck is the base class for all Zod checks, accepting a single generic parameter T. It contains a _zod property with internals including .def (the check's definition with .def.check as a string representing the check type) and .check() (the check's validation logic).

$ZodChecks union of all first-party check classes

zod/v4/core exports a union type $ZodChecks including: $ZodCheckLessThan, $ZodCheckGreaterThan, $ZodCheckMultipleOf, $ZodCheckNumberFormat, $ZodCheckBigIntFormat, $ZodCheckMaxSize, $ZodCheckMinSize, $ZodCheckSizeEquals, $ZodCheckMaxLength, $ZodCheckMinLength, $ZodCheckLengthEquals, $ZodCheckProperty, $ZodCheckMimeType, $ZodCheckOverwrite, and $ZodCheckStringFormat.

Discriminating between checks - pattern

To discriminate between check types, use check._zod.def.check property to determine the check type (e.g. 'less_than', 'greater_than', 'string_format'). For string format checks, use a nested switch on formatCheck._zod.def.format.

Refinement methods

Three refinement methods are available: refine() for custom validation logic, superRefine() which is deprecated in favor of check(), and overwrite() for overwriting schema behavior.

z.refine() for custom validation logic

z.string().refine() accepts a validation function that returns a truthy value for valid input. Refinement functions should never throw; they should return a falsy value to signal failure. The function receives the parsed value as its argument.

Refinements are continuable by default

By default, validation issues from refinements are considered continuable, meaning Zod will execute all refinement checks in sequence even if one fails. This allows multiple validation errors to be surfaced at once. Use the abort parameter set to true to make a refinement non-continuable; validation will terminate if that check fails.

z.refine() path parameter customizes error path

The path parameter in .refine() customizes the error path. This is typically only useful in the context of object schemas.

async refinements require parseAsync method

If you use async refinements with .refine(), you must use the .parseAsync() method to parse data. Otherwise Zod will throw an error. Example: const userId = z.string().refine(async (id) => { return true; }); const result = await userId.parseAsync("abc123");

refine when parameter controls execution conditions

The when parameter on .refine() controls whether a refinement runs based on validation state. It receives a payload object and should return a boolean indicating whether the refinement should execute. This allows refinements to run even when other non-dependent fields have validation errors. For example: when(payload) { return baseSchema.pick({ password: confirmPassword }).safeParse(payload.value).success; }

superRefine() allows multiple issues with any error code

The .superRefine() method allows creating multiple validation issues using any of Zod's internal issue types (not just "custom"). It receives (val, ctx) parameters and uses ctx.addIssue() to add issues. Example: .superRefine((val, ctx) => { ctx.addIssue({ code: "too_big", maximum: 3, origin: "array", inclusive: true, message: "Too many items 😡", input: val }); })

check() API for low-level issue control

The .check() method is a lower-level API for creating custom refinements with full control over issue objects. It receives a ctx parameter where you can directly push issues to ctx.issues. Issues can have a continue: true property to make them continuable (default: false). The .check() API is more verbose than .superRefine() but can be faster in performance-sensitive code.

Refinements stored inside schemas in Zod 4

In Zod 4, refinements are stored inside schemas themselves instead of wrapping them in ZodEffects. This allows interleaving .refine() with other methods: z.string().refine(val => val.includes('@')).min(5) now works.

.overwrite() method for non-transforming overwrites

z.number().overwrite(val => val ** 2) returns a ZodNumber (not ZodPipe) and doesn't change the inferred type. Unlike .transform(), .overwrite() is introspectable at runtime and can be converted to JSON Schema. Used internally by .trim(), .toLowerCase(), .toUpperCase().

Give your agent this brain