Capítulo 59 de 61
Most Zod 4 internal restructuring (generics, the new zod/v4/core package, the _zod.def internals location, and the refinement/transform class split) doesn't affect typical application code, but matters directly to anyone building tooling on top of Zod.
| Area | Zod 3 | Zod 4 |
|---|---|---|
ZodType generics | ZodType<Output, Def extends ZodTypeDef, Input = Output> | ZodType<Output = unknown, Input = unknown> — the Def generic is gone, Input now defaults to unknown instead of Output |
z.ZodTypeAny | needed as a catch-all type | unnecessary — plain z.ZodType now serves that purpose |
| Shared core code | not split out | moved to zod/v4/core, re-exported from both zod and zod/mini as the z.core namespace |
| Internal definition property | ._def | ._zod.def |
| Refinements & transforms | both lived inside a ZodEffects wrapper class | refinements now live as "checks" directly inside each schema; transforms live in a dedicated ZodTransform class |
.transform() return type | its own effects wrapper | returns a ZodPipe<OriginalSchema, ZodTransform> |
z.preprocess() return type | ZodPreprocess instance | returns a ZodPipe<ZodTransform, TargetSchema> |
| Branded types | dedicated ZodBranded wrapper class | direct modification of the inferred type, no wrapper class; user-facing API unchanged |
// generics: T is inferred as the caller's actual schema class, not a fixed Output type
function inferSchema<T extends z.ZodType>(schema: T): T { return schema; }
inferSchema(z.string()); // => ZodString
// zod/v4/core re-exported as z.core from the main package
import * as z from "zod";
function handleError(iss: z.core.$ZodError) { /* ... */ }
// standalone transforms are now first-class
const schema = z.transform(input => String(input));
schema.parse(12); // => "12"
// .transform() now composes via ZodPipe under the hood
z.string().transform(val => val); // ZodPipe<ZodString, ZodTransform>
z.core, and the new first-class standalone-transform capability.._def moved to ._zod.def — any tooling reading Zod internals directly needs updating for this new location.ZodEffects/ZodBranded/ZodPreprocess classes are gone; tooling that pattern-matched on those specific class names needs to switch to checking ._zod.def.type/.def.check discriminants instead._zod.def and the core class hierarchy this migration moved toward."zod/v4/core" import path this restructuring introduced.