Libraries
    Preparing search index...

    Class SchemaBuilder<TResult, TRequired, TNullable, THasDefault, TExtensions>Abstract

    Base class for all schema builders. Provides basic functionality for schema building.

    Note: this class is not intended to be used directly, use one of the subclasses instead.

    TResult Type of the object that will be returned by validate() method.

    TRequired If true, object will be required. If false, object will be optional.

    Type Parameters

    • TResult = any
    • TRequired extends boolean = true
    • TNullable extends boolean = false
    • THasDefault extends boolean = false
    • TExtensions = {}

    Hierarchy (View Summary)

    Index

    Constructors

    Properties

    "[___hasDefault]": THasDefault

    Type-level brand encoding whether this schema has a default value. Not emitted at runtime — used by input type inference.

    "[___type]": TRequired extends true
        ? TNullable extends true ? TResult | null : TResult
        : (TNullable extends true ? TResult | null : TResult) | undefined

    Type-level brand encoding the inferred type of this schema. Not emitted at runtime — used only by InferType.

    Accessors

    • get "~standard"(): StandardSchemaV1.Props<
          ResolvedSchemaType<TResult, TRequired, TNullable>,
      >

      Standard Schema v1 interface.

      Exposes this schema as a Standard Schema v1 validator, enabling out-of-the-box interoperability with any library that consumes the spec — including tRPC, TanStack Form, React Hook Form, T3 Env, Hono, Elysia, next-safe-action, and 50+ other tools.

      Every SchemaBuilder subclass (all 13 builders) inherits this property automatically — no additional setup required.

      Shape of the returned object:

      • version — always 1 (Standard Schema spec version)
      • vendor'@cleverbrush/schema'
      • validate(value) — synchronous; wraps this builder's own .validate() and converts its result to the Standard Schema Result<Output> format:
        • Success: { value: <validated output> }
        • Failure: { issues: [{ message: string }, …] }

      The returned object is cached after the first access so repeated reads return the same reference (required by the spec).

      Returns StandardSchemaV1.Props<ResolvedSchemaType<TResult, TRequired, TNullable>>

      import { object, string, number } from '@cleverbrush/schema';

      const UserSchema = object({
      name: string().minLength(2),
      email: string().email(),
      age: number().min(18).optional(),
      });

      // Grab the Standard Schema interface
      const std = UserSchema['~standard'];
      // std.version === 1
      // std.vendor === '@cleverbrush/schema'

      const ok = std.validate({ name: 'Alice', email: 'alice@example.com' });
      // { value: { name: 'Alice', email: 'alice@example.com', age: undefined } }

      const fail = std.validate({ name: 'A', email: 'not-an-email' });
      // { issues: [{ message: 'minLength' }, { message: 'email' }] }

      // Pass directly to TanStack Form, T3 Env, tRPC, etc.:
      // validators: { onChange: UserSchema, onBlur: UserSchema }
    • get canSkipPreValidation(): boolean

      Whether preValidateSync can be skipped entirely. True when there are no preprocessors and no validators, so the only work would be the required check and wrapping in a noop transaction — which subclasses can do inline.

      Returns boolean

    • get hasCatch(): boolean

      Whether this schema has a catch/fallback value configured via .catch().

      Returns boolean

    • get hasDefault(): boolean

      Whether this schema has a default value configured via .default(). Exposed for fast-path validation in subclasses.

      Returns boolean

    • get isNullable(): boolean

      Whether null is an accepted value for this schema.

      Returns boolean

    • get isNullRequiredViolation(): boolean
      Protected

      Whether null should count as a required-constraint violation.

      By default null is treated the same as undefined for the purposes of the required check — i.e. a required schema rejects both. Subclasses that may legally receive null as a value (e.g. UnionSchemaBuilder when a NullSchemaBuilder option is present) can override this to false so that null bypasses the required check and is passed directly to their option-validation logic.

      Returns boolean

    • get isReadonly(): boolean

      Whether this schema is marked as readonly. Type-level only — no runtime enforcement.

      Returns boolean

    • get isRequired(): TRequired

      Whether the schema requires a non-null/non-undefined value.

      Returns TRequired

    • set isRequired(value: boolean): void

      Sets the requirement flag. Must be a boolean.

      Parameters

      • value: boolean

      Returns void

    • get preprocessors(): PreprocessorEntry<TResult>[]

      A list of preprocessors associated with the Builder

      Returns PreprocessorEntry<TResult>[]

    • get type(): string

      The string identifier of the schema type (e.g. 'string', 'number', 'object').

      Returns string

    • set type(value: string): void

      Sets the schema type identifier. Must be a non-empty string.

      Parameters

      • value: string

      Returns void

    • get validators(): ValidatorEntry<TResult>[]

      A list of validators associated with the Builder

      Returns ValidatorEntry<TResult>[]

    Methods

    • Internal

      Perform synchronous schema validation on object. Throws at runtime if any preprocessor, validator, or error message provider returns a Promise — use validateAsync instead. Override this in subclasses. External callers use validate.

      Parameters

      • object: any
      • Optionalcontext: ValidationContext<SchemaBuilder<any, any, any, any, {}>>

      Returns ValidationResult<any>

    • Internal

      Perform asynchronous schema validation on object. Supports async preprocessors, validators, and error message providers. Override this in subclasses. External callers use validateAsync.

      Parameters

      • object: any
      • Optionalcontext: ValidationContext<SchemaBuilder<any, any, any, any, {}>>

      Returns Promise<ValidationResult<any>>

    • Adds a preprocessor to a preprocessors list

      Parameters

      • preprocessor: Preprocessor<TResult>
      • Optionaloptions: { mutates?: boolean }

      Returns this

    • Adds a validator to validators list.

      Parameters

      • validator: Validator<TResult>
      • Optionaloptions: { mutates?: boolean }

      Returns this

    • Brands the schema with a phantom type tag, preventing structural mixing of semantically different values at the type level. Zero runtime cost.

      The optional _name parameter is only needed when using plain JavaScript (where generic type parameters are unavailable). In TypeScript, prefer the generic form: schema.brand<'Email'>().

      Type Parameters

      • TBrand extends string | symbol

      Parameters

      Returns any

      const Email = string().brand<'Email'>();
      const Username = string().brand<'Username'>();
      type Email = InferType<typeof Email>; // string & { readonly [BRAND]: 'Email' }
      type Username = InferType<typeof Username>; // string & { readonly [BRAND]: 'Username' }
    • Sets a fallback value for this schema. When validation fails for any reason, the fallback value is returned as a successful result instead of validation errors.

      This is useful for graceful degradation — for example, providing a safe default when parsing untrusted input that might not conform to the schema.

      Accepts either a static value or a factory function. Factory functions are called each time the fallback is needed (useful for mutable values like () => []).

      Unlike default, which only fires when the input is undefined, .catch() fires on any validation failure — type mismatch, constraint violation, etc.

      When .catch() is set, parse and parseAsync will never throw.

      Parameters

      • value: TResult | (() => TResult)

        the fallback value, or a factory function producing the fallback

      Returns this

      const schema = string().catch('unknown');
      schema.validate(42); // { valid: true, object: 'unknown' }
      schema.validate('hello'); // { valid: true, object: 'hello' }
      schema.parse(42); // 'unknown' (no throw)
      // Factory function for mutable fallbacks
      const schema = array(string()).catch(() => []);
      schema.validate(null); // { valid: true, object: [] }
      // Contrast with .default() — default fires only on undefined
      const d = string().default('anon');
      d.validate(undefined); // { valid: true, object: 'anon' } ← fires
      d.validate(42); // { valid: false, errors: [...] } ← does NOT fire

      const c = string().catch('anon');
      c.validate(undefined); // { valid: true, object: 'anon' } ← fires
      c.validate(42); // { valid: true, object: 'anon' } ← also fires
    • Removes the default value set by a previous call to .default().

      Returns any

    • Clears type set by call to .hasType<T>(), default schema type inference will be used for schema returned by this call.

      Returns any

    • Remove all preprocessors for this schema.

      Returns this

    • Remove all validators for this schema.

      Returns this

    • Protected method used to create a new instance of the Builder defined by the props object. Should be used to instantiate new builders to keep builder's immutability.

      Parameters

      • props: any

        arbitrary props object

      Returns this

    • Sets a default value for this schema. When the input is undefined, the default value is used instead. The default is still validated against the schema's constraints.

      Accepts either a static value or a factory function (useful for mutable defaults like () => new Date() or () => []).

      Parameters

      Returns any

      const schema = string().default('hello');
      schema.validate(undefined); // { valid: true, object: 'hello' }
      schema.validate('world'); // { valid: true, object: 'world' }
      // Factory function for mutable defaults
      const schema = array(string()).default(() => []);
    • Attaches a human-readable description to this schema as runtime metadata.

      The description has no effect on validation — it is purely informational. It is accessible via .introspect().description and is emitted as the description field by toJsonSchema() from @cleverbrush/schema-json.

      Useful for documentation generation, form labels, and AI tool descriptions.

      Parameters

      • text: string

      Returns this

      const schema = object({
      name: string().describe('The user\'s full name'),
      age: number().optional().describe('Age in years'),
      }).describe('A user object');

      schema.introspect().description; // 'A user object'
    • Internal

      Retrieves extension metadata by key. Used by extension authors inside defineExtension() callbacks.

      Parameters

      • key: string

      Returns unknown

    • Resolves a ValidationErrorMessageProvider to a string error message. Handles both string providers and function providers (sync or async).

      Parameters

      Returns Promise<string>

      the resolved error message string

    • Synchronously resolves a ValidationErrorMessageProvider to a string. Throws if the provider function returns a Promise.

      Parameters

      Returns string

      the resolved error message string

      Error if the provider returns a Promise (use getValidationErrorMessage with validateAsync)

    • Set type of schema explicitly. notUsed param is needed only for case when JS is used. E.g. when you can't call method like schema.hasType<Date>(), so instead you can call schema.hasType(new Date()) with the same result.

      Type Parameters

      • T

      Parameters

      • OptionalnotUsed: T

      Returns any

    • Generates a serializable object describing the defined schema

      Returns {
          catchValue: TResult | (() => TResult) | undefined;
          defaultValue: TResult | (() => TResult) | undefined;
          description: string | undefined;
          extensions: { [key: string]: unknown };
          hasCatch: boolean;
          hasDefault: boolean;
          isNullable: boolean;
          isReadonly: boolean;
          isRequired: boolean;
          preprocessors: readonly PreprocessorEntry<TResult>[];
          requiredValidationErrorMessageProvider: ValidationErrorMessageProvider<
              SchemaBuilder<any, any, any, any, any>,
          >;
          type: string;
          validators: readonly ValidatorEntry<TResult>[];
      }

      • catchValue: TResult | (() => TResult) | undefined

        The catch/fallback value or factory function set via .catch().

      • defaultValue: TResult | (() => TResult) | undefined

        The default value or factory function.

      • description: string | undefined

        The human-readable description attached to this schema via .describe(), or undefined if none was set.

      • extensions: { [key: string]: unknown }

        Extension metadata. Stores custom state set by schema extensions.

      • hasCatch: boolean

        Whether a catch/fallback value has been set on this schema via .catch().

      • hasDefault: boolean

        Whether a default value (or factory) has been set on this schema.

      • isNullable: boolean

        If set to true, schema values of null are considered valid.

      • isReadonly: boolean

        If set to true, the inferred type is marked as readonly. Type-level only — no runtime enforcement.

      • isRequired: boolean

        If set to false, schema will be optional (null or undefined values will be considered as valid).

      • preprocessors: readonly PreprocessorEntry<TResult>[]

        Array of preprocessor functions

      • requiredValidationErrorMessageProvider: ValidationErrorMessageProvider<SchemaBuilder<any, any, any, any, any>>

        Custom error message provider for the 'is required' validation error.

      • type: string

        String id of schema type, e.g. string', numberorobject`.

      • validators: readonly ValidatorEntry<TResult>[]

        Array of validator functions

    • Removes the nullable mark — null is no longer accepted as a valid value. This is the counterpart of .nullable().

      Returns any

    • Makes schema nullable — null is accepted as a valid value.

      Unlike .optional() which accepts undefined, .nullable() accepts null. The inferred type changes from T to T | null. Combine with .optional() to accept both null and undefined.

      Returns any

    • Makes schema optional (consider null and undefined as valid objects for this schema)

      Returns any

    • Synchronously validates the value and returns it if valid. Throws a SchemaValidationError if validation fails.

      Parameters

      • object: any

        the value to parse

      • Optionalcontext: ValidationContext<SchemaBuilder<any, any, any, any, {}>>

        optional validation context

      Returns TResult

      the validated value

      SchemaValidationError if validation fails

      Error if the schema contains async preprocessors, validators, or error message providers

    • Asynchronously validates the value and returns it if valid. Throws a SchemaValidationError if validation fails.

      Parameters

      • object: any

        the value to parse

      • Optionalcontext: ValidationContext<SchemaBuilder<any, any, any, any, {}>>

        optional validation context

      Returns Promise<TResult>

      the validated value

      SchemaValidationError if validation fails

    • Parameters

      • object: any
      • Optionalcontext: ValidationContext<SchemaBuilder<any, any, any, any, {}>>

      Returns Promise<PreValidationResult<any, { validatedObject: any }>>

      Use preValidateAsync instead. This alias will be removed in a future version.

    • Async version of pre-validation. Runs preprocessors, validators, and the required/optional check on object. Supports async preprocessors, validators, and error message providers.

      Parameters

      • object: any

        the value to pre-validate

      • Optionalcontext: ValidationContext<SchemaBuilder<any, any, any, any, {}>>

        optional validation context settings

      Returns Promise<PreValidationResult<any, { validatedObject: any }>>

      a PreValidationResult containing the preprocessed transaction, context, and any errors

    • Synchronous version of preValidateAsync. Throws at runtime if any preprocessor or validator returns a Promise.

      Parameters

      • object: any

        the value to pre-validate

      • Optionalcontext: ValidationContext<SchemaBuilder<any, any, any, any, {}>>

        optional validation context settings

      Returns PreValidationResult<any, { validatedObject: any }>

      a PreValidationResult containing the preprocessed transaction, context, and any errors

      Error if a preprocessor or validator returns a Promise (use preValidateAsync instead)

    • Marks the inferred type as readonly. For objects, produces Readonly<T>. For arrays, produces ReadonlyArray<T>. Primitives are unchanged. Type-level only — no runtime enforcement.

      Returns any

      const schema = object({ name: string(), age: number() }).readonly();
      type T = InferType<typeof schema>; // Readonly<{ name: string; age: number }>
      const schema = array(string()).readonly();
      type T = InferType<typeof schema>; // ReadonlyArray<string>
    • Makes schema required (consider null and undefined as invalid objects for this schema)

      Parameters

      Returns any

    • Resolves the catch/fallback value. If the stored value is a factory function, it is called to produce the value (useful for mutable fallbacks like () => []).

      Returns TResult

    • Resolves the default value. If the stored default is a function, it is called to produce the value (useful for mutable defaults).

      Returns TResult

    • Alias for validate. Synchronously validates and returns a result object. Provided for familiarity with the zod API.

      Parameters

      • object: any
      • Optionalcontext: ValidationContext<SchemaBuilder<any, any, any, any, {}>>

      Returns ValidationResult<TResult>

    • Alias for validateAsync. Asynchronously validates and returns a result object. Provided for familiarity with the zod API.

      Parameters

      • object: any
      • Optionalcontext: ValidationContext<SchemaBuilder<any, any, any, any, {}>>

      Returns Promise<ValidationResult<TResult>>

    • Perform synchronous schema validation on object. Throws at runtime if any preprocessor, validator, or error message provider returns a Promise — use validateAsync instead.

      If a fallback has been set via catch, a failed validation result is replaced by a successful result built from the fallback value, preserving the specialized result shape (e.g. getErrorsFor / getNestedErrors methods).

      Parameters

      • object: any

        Object to validate

      • Optionalcontext: ValidationContext<SchemaBuilder<any, any, any, any, {}>>

        Optional ValidationContext settings

      Returns ValidationResult<any>

    • Perform asynchronous schema validation on object. Supports async preprocessors, validators, and error message providers.

      If a fallback has been set via catch, a failed validation result is replaced by a successful result built from the fallback value, preserving the specialized result shape (e.g. getErrorsFor / getNestedErrors methods).

      Parameters

      • object: any

        Object to validate

      • Optionalcontext: ValidationContext<SchemaBuilder<any, any, any, any, {}>>

        Optional ValidationContext settings

      Returns Promise<ValidationResult<any>>

    • Internal

      Sets extension metadata by key. Returns a new schema instance with the extension data stored. The data survives fluent chaining. Used by extension authors inside defineExtension() callbacks.

      Parameters

      • key: string
      • value: unknown

      Returns this