Skip to content

Arrays and Other Schemas

Preview ZodSharp Reviewed 2026-09-16 purview-dev/zodsharp aspnetcore c-sharp csharp dotnet json-schema newtonsoft-json schema source-generator system-text-json validation zero-allocation zod

ZodArray<T> (namespace ZodSharp.Schemas) validates T[] values. Each element is validated against the element schema; failures carry index paths such as ["0"]. 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
Max(int maxLength, string? message) too_big when count > max
Length(int length, string? message) exact length (both bounds)
NonEmpty(string? message) minLength = 1

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();

ZodEnum validates against a set of allowed strings. Failure produces invalid_enum_value.

var schema = Z.Enum("admin", "user", "guest");

ZodNativeEnum<TEnum> validates a native System.Enum using Enum.IsDefined. Failure produces invalid_enum_value.

var schema = Z.Enum<Color>(); // Color : struct, Enum

ZodLiteral<T> (where T : IEquatable<T>) accepts exactly one value. Failure produces invalid_literal.

var schema = Z.Literal("active");
var schema2 = Z.Literal(42);

ZodRecord<TValue> validates Dictionary<string, TValue>, validating every value against the value schema with key-prefixed error paths. It always produces a fresh validated dictionary.

var schema = Z.Record(Z.Number());

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 value

Failures: invalid_type on null, invalid_tuple_length on wrong length, and per-index invalid_type with paths like ["[0]"].

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());

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); // Success
optional.Validate("value"); // Success