Primate LogoPrimate

Composition and special schemas

Unions and literals

p.union(...members) tries each normalized member and accepts the first schema that parses. A union requires at least two members.

const Theme = p.union("light", "dark");
const Identifier = p.union(p.u32, p.uuid);

UnionType supports optional() and default(). When every branch fails it produces one invalid_type issue describing the union.

p.literal(value) creates LiteralType for a string, number or boolean. Passing one of those values directly to callable p is equivalent.

Null and undefined

p.null and p.undefined accept exactly those values and return NullType and UndefinedType. Compose them with a union when nullability is part of the runtime contract:

const Name = p.union(p.string, null);

Use optional() when absence or undefined is the intended object-input behavior.

Predicates

p.is(predicate) creates IsType from a TypeScript type guard:

type Point = { x: number; y: number };

const Point = p.is((value): value is Point => {
  if (typeof value !== "object" || value === null) return false;
  const point = value as Record<string, unknown>;
  return typeof point.x === "number" && typeof point.y === "number";
});

The predicate is the validation contract. IsType supports optional() and default() but does not define a Store datatype.

Primitive schemas offer check() when a type has already been parsed and only an additional boolean condition is needed.

Class instances

p.constructor(Class) creates ConstructorType and accepts instances of that class or its subclasses:

class Token {}
const TokenSchema = p.constructor(Token);

Callable p(Token) is equivalent. Constructor schemas support optional() and default() and are validation-only.

Unchecked values

p.pure<T>() supplies a static TypeScript type but returns every runtime input unchanged. p.unknown is its unknown-typed counterpart. Neither validates the value:

const External = p.pure<{ id: string }>();
External.parse(42); // accepted and typed as { id: string }

Use these only at a boundary that is already trusted. PureType and UnknownType are not Store fields.

Functions and symbols

p.function accepts functions and returns FunctionType; p.symbol accepts symbols. These schemas are useful for configuration and in-memory contracts, but cannot be persisted directly by a Store.

Most schemas on this page are validation-only. For structured persistent data, use p.json(inner) when the parsed value is JSON-compatible.

Previous
Collections
Next
Errors