Documentation section: Schemas
Arrays and Other Schemas
Prerelease. These pages describe 3.0.0-prerelease.2 and can differ from the published release. Read the Live 2.4.2 documentation instead.
Arrays and Other Schemas
Section titled “Arrays and Other Schemas”Arrays
Section titled “Arrays”ZodArray<T> (namespace ZodSharp.Schemas) validates T[] values. Each element is validated against the element schema; failures are re-pathed under a typed index segment, keeping every field of the element’s error, so FullPath.ToDottedString() renders [1] (or items[1] inside an object) and the legacy Path is ["1"] (it used to be ["[1]"]). A null array reports "Expected array, received null". A rebuilt array is produced only when a transform changed an element.
using ZodSharp;
var numbers = Z.Array(Z.Number()).Min(1).Max(10);var result = numbers.Validate(new[] { 1.0, 2.0, 3.0 });| Method | Behaviour |
|---|---|
Min(int minLength, string? message) |
too_small when count < min: "Array must have at least 2 elements, but got 1" |
Max(int maxLength, string? message) |
too_big when count > max: "Array must have at most 2 elements, but got 3" |
Length(int length, string? message) |
exact length (both bounds): "Array must have exactly 2 elements, but got 3" |
NonEmpty(string? message) |
minLength = 1 |
Size failures carry origin array, both configured bounds as Lower/Upper (inclusive) and the element count in
the count parameter. Min, Max and Length keep separate custom messages, so Min(2, "few").Max(5, "many")
reports the message of the bound that failed.
Boolean
Section titled “Boolean”ZodBoolean validates bool; there are no fluent methods.
var schema = Z.Boolean();ZodNull succeeds only for null input, and implements IAcceptsNull so it can serve as an object field accepting null.
var schema = Z.Null();ZodDate validates DateTime values, with optional inclusive .Min/.Max bounds. Equivalent to Zod’s z.date().
var schema = Z.Date().Min(new DateTime(2020, 1, 1)).Max(new DateTime(2030, 12, 31));BigInt
Section titled “BigInt”ZodBigInt validates 64-bit integers (long), with .Min, .Max, .Gt, .Gte, .Lt, .Lte, .Positive,
.Negative, .NonNegative, and .NonPositive. Equivalent to Zod’s z.bigint().
var schema = Z.BigInt().Positive().Max(9_000_000_000);Enum (string values)
Section titled “Enum (string values)”ZodEnum validates against a set of allowed strings. Failure produces invalid_enum_value (category invalid_value, origin enum) with the message "Expected one of: admin, guest, user" (options in ordinal order) and the options parameter; the received value is not echoed.
var schema = Z.Enum("admin", "user", "guest");Native enum
Section titled “Native enum”ZodNativeEnum<TEnum> validates a native System.Enum using Enum.IsDefined. Failure produces invalid_enum_value, reported exactly as EnumRule reports it, with the options listed in ordinal order.
var schema = Z.Enum<Color>(); // Color : struct, EnumLiteral
Section titled “Literal”ZodLiteral<T> (where T : IEquatable<T>) accepts exactly one value. Failure produces invalid_literal (category invalid_value) with the message "Expected literal active" and the literal in the expected parameter; the received value is not echoed.
var schema = Z.Literal("active");var schema2 = Z.Literal(42);Record
Section titled “Record”ZodRecord<TValue> validates Dictionary<string, TValue>, validating every value against the value schema. Errors are re-pathed under a typed key segment (rendered with the invariant culture): [en], or ["0"]/["a.b"] when the key would otherwise be ambiguous. It always produces a fresh validated dictionary.
var schema = Z.Record(Z.Number());A null value is the value schema’s decision: Z.Record(Z.String()) rejects it, while
Z.Record(Z.Optional(Z.String())) accepts it. The schema exports and imports as
{ "type": "object", "additionalProperties": … } (see
JSON Schema Export), and a generated Dictionary<TKey, TValue>
property is validated the same way.
ZodTuple validates fixed-length tuples. Two- and three-element overloads exist; input is object?[].
var schema = Z.Tuple(Z.String(), Z.Number());
var result = schema.Validate(new object?[] { "John", 30.0 });// (string, double) success valueFailures:
nullinput →invalid_type("Expected tuple, received null").- Wrong length →
invalid_tuple_lengthwith categorytoo_small/too_big, originarrayand both bounds equal to the arity ("Expected tuple of length 2, but got 3"). - Element failures are prefixed with the element’s index (
[0]; legacyPath["0"]). A type mismatch reads"Expected string, received number". They used to be reported at the tuple root. - A
nullelement is handed to the element schema when its type can holdnull, soZ.Optional(...)elements accept it.
ZodLazy<T> defers schema construction to first use, enabling recursive and circular schemas. The inner Schema is resolved lazily and thread-safely.
var categorySchema = Z.Lazy<Dictionary<string, object?>>(() => Z.Object() .Field("name", Z.String()) .Field("subcategories", Z.Array(categorySchema)) .Build());Optional / Nullable
Section titled “Optional / Nullable”Z.Optional<T>(schema) (T : class) accepts null or a value matching the inner schema. Z.Nullable<T>(schema) (T : struct) is the value-type counterpart.
var optional = Z.Optional(Z.String());optional.Validate(null); // Successoptional.Validate("value"); // SuccessFor a generated collection, element nullability follows the element type: T[]/List<T> rejects null elements, while T?[]/List<T?> accepts them — the same distinction as z.array(T) versus z.array(T.nullable()). A dictionary property (IDictionary<,>/IReadOnlyDictionary<,>) is a map instead: values are validated like elements, and it maps to z.record(z.string(), V). See Collection null items.