Capítulo 51 de 61

Chapter 51: Zod Core — Schema Classes & Internals

Core Idea

zod/v4/core is the unopinionated base library that both Zod Classic and Zod Mini extend — its schema classes carry only internal state (a single _zod property), no user-facing methods, so downstream packages (or your own tooling) can build whatever API surface they want on top.

Key Concepts

  • $ZodType<Output, Input>: the base class for every schema, generic over output and input types. First-party subclasses (string, number, object, array, union, etc.) are collected in the $ZodTypes union type for exhaustive switch-style handling.
  • String format subclasses: $ZodString has many further subclasses for specific formats ($ZodEmail, $ZodUUID, $ZodURL, $ZodISODateTime, $ZodIPv4, $ZodJWT, etc.), collected in $ZodStringFormatTypes.
  • _zod internals: every core schema instance exposes just this one property, containing .def (the JSON-serializable definition object passed to the constructor — .def.type is a string discriminant like "string"/"object", .def.checks is the array of checks), .input/.output (virtual type-only properties for inferred types), and .run() (the internal parser implementation).
  • Traversal pattern: cast a schema to $ZodTypes and switch on schema._zod.def.type to build tooling (code generators, schema walkers) that discriminates between concrete schema classes.
  • No instance methods at the core level: .parse()/.safeParse()/etc. don't exist on core classes — they're added by Zod Classic/Mini. Core package consumers use top-level functions instead (z.parse(schema, data), z.safeParse(), z.parseAsync(), z.safeParseAsync()).

Code Examples

import * as z from "zod/v4/core";

// traversal via the def discriminant
function walk(_schema: z.$ZodType) {
  const schema = _schema as z.$ZodTypes;
  const def = schema._zod.def;
  switch (def.type) {
    case "string": /* ... */ break;
    case "object": /* ... */ break;
  }
}

// parsing at the core level uses top-level functions, not instance methods
const schema = new z.$ZodString({ type: "string" });
z.parse(schema, "hello");
await z.parseAsync(schema, "hello");
  • What it demonstrates: introspecting a schema's concrete type via .def.type, and parsing through the core package's function-based API rather than instance methods.

Key Takeaways

  1. zod/v4/core schemas are pure data-plus-internals — treat _zod.def as the stable, serializable description of a schema for any tool that needs to introspect or generate code from schemas.
  2. Because core classes have no parsing methods, any code operating purely at the core level (e.g. cross-Zod/Zod-Mini library code) must use z.parse()/z.safeParse() as top-level functions.
  3. The $ZodTypes and $ZodStringFormatTypes unions are the reference point for exhaustively handling every first-party schema/format type in tooling.

Connects To

  • For Library Authors — Accepting User-Defined Schemas: the generic-typing pattern used when writing functions that operate on $ZodType.
  • Zod Core — Parsing, Checks, Errors & Issues: the rest of the core package's surface, covered next.