valrs

Types

TypeScript type definitions for valrs

Type Definitions

Complete TypeScript type definitions exported by valrs.

Type Inference Utilities

v.infer<T>

Infers the output type from a schema. This is the primary type inference utility, matching Zod's z.infer.

type infer<T extends ValSchema<unknown, unknown>> =
  T extends ValSchema<unknown, infer O> ? O : never;

Usage:

import { v } from 'valrs';
 
const userSchema = v.object({
  name: v.string(),
  age: v.number(),
  email: v.string().email(),
});
 
// Infer the output type
type User = v.infer<typeof userSchema>;
// { name: string; age: number; email: string }
 
// Works with all schema types
const arraySchema = v.array(v.string());
type StringArray = v.infer<typeof arraySchema>; // string[]
 
const unionSchema = v.union([v.string(), v.number()]);
type StringOrNumber = v.infer<typeof unionSchema>; // string | number

v.input<T>

Infers the input type from a schema. Use this when the input type differs from the output type (e.g., with coercion or transforms).

type input<T extends ValSchema<unknown, unknown>> =
  T extends ValSchema<infer I, unknown> ? I : never;

Usage:

import { v } from 'valrs';
 
// With coercion, input differs from output
const schema = v.coerce.number();
type Input = v.input<typeof schema>;   // unknown
type Output = v.output<typeof schema>; // number
 
// With transforms
const dateSchema = v.string().transform((s) => new Date(s));
type DateInput = v.input<typeof dateSchema>;  // string
type DateOutput = v.output<typeof dateSchema>; // Date

v.output<T>

Infers the output type from a schema. This is an alias for v.infer that provides symmetry with v.input.

type output<T extends ValSchema<unknown, unknown>> = Infer<T>;

Usage:

import { v } from 'valrs';
 
const schema = v.string().transform((s) => s.length);
 
type Input = v.input<typeof schema>;   // string
type Output = v.output<typeof schema>; // number (same as v.infer)

SafeParse Result Types

SafeParseResult<T>

The result of a safeParse() call. A discriminated union that is either a success or failure.

type SafeParseResult<T> = SafeParseSuccess<T> | SafeParseError;

Usage:

import { v } from 'valrs';
 
const schema = v.string().min(3);
const result = schema.safeParse(input);
 
if (result.success) {
  // TypeScript knows result.data is string
  console.log(result.data.toUpperCase());
} else {
  // TypeScript knows result.error is ValError
  console.log(result.error.issues);
}

SafeParseSuccess<T>

The result of a successful safeParse() call.

interface SafeParseSuccess<T> {
  readonly success: true;
  readonly data: T;
  readonly error?: undefined;
}
PropertyTypeDescription
successtrueDiscriminator indicating success
dataTThe validated and parsed value
errorundefinedAlways undefined on success

SafeParseError

The result of a failed safeParse() call.

interface SafeParseError {
  readonly success: false;
  readonly error: ValError;
  readonly data?: undefined;
}
PropertyTypeDescription
successfalseDiscriminator indicating failure
errorValErrorThe error containing validation issues
dataundefinedAlways undefined on failure

Type Guards

import { v, isSafeParseSuccess, isSafeParseError } from 'valrs';
 
const result = v.string().safeParse(input);
 
// Using type guards
if (isSafeParseSuccess(result)) {
  console.log(result.data);
}
 
if (isSafeParseError(result)) {
  console.log(result.error.message);
}

Error Types

ValError

Error class thrown when schema.parse() fails. Contains detailed information about all validation issues with Zod-compatible error codes and formatting methods.

class ValError extends Error {
  readonly name: 'ValError';
  readonly issues: ReadonlyArray<ValIssue>;
 
  constructor(issues: ReadonlyArray<ValidationIssue>);
 
  // Instance methods
  get firstError(): ValIssue | undefined;
  hasErrorAt(path: ReadonlyArray<string | number>): boolean;
  errorsAt(path: ReadonlyArray<string | number>): ReadonlyArray<ValIssue>;
  format<T = unknown>(): FormattedError<T>;
  flatten<T = unknown>(): FlattenedError<T>;
  addIssue(issue: ValIssue): ValError;
  addIssues(issues: ReadonlyArray<ValIssue>): ValError;
 
  // Static methods
  static fromValIssues(issues: ReadonlyArray<ValIssue>): ValError;
  static isValError(value: unknown): value is ValError;
}

Usage:

import { v, ValError } from 'valrs';
 
try {
  v.string().parse(123);
} catch (error) {
  if (error instanceof ValError) {
    // Access all issues
    console.log(error.issues);
    // [{ code: 'invalid_type', path: [], message: '...', expected: 'string', received: 'number' }]
 
    // Get first error
    console.log(error.firstError?.message);
 
    // Check for errors at a specific path
    if (error.hasErrorAt(['user', 'email'])) {
      const emailErrors = error.errorsAt(['user', 'email']);
    }
 
    // Format as nested object
    console.log(error.format());
    // { _errors: ['Expected string, received number'] }
 
    // Flatten for form handling
    console.log(error.flatten());
    // { formErrors: ['Expected string, received number'], fieldErrors: {} }
  }
}

ValIssue

Union of all issue types. Each issue has a code discriminator that determines its shape.

type ValIssue =
  | InvalidTypeIssue
  | InvalidLiteralIssue
  | CustomIssue
  | InvalidUnionIssue
  | InvalidUnionDiscriminatorIssue
  | InvalidEnumValueIssue
  | UnrecognizedKeysIssue
  | InvalidArgumentsIssue
  | InvalidReturnTypeIssue
  | InvalidDateIssue
  | InvalidStringIssue
  | TooSmallIssue
  | TooBigIssue
  | InvalidIntersectionTypesIssue
  | NotMultipleOfIssue
  | NotFiniteIssue;

ValIssueCode

All possible Zod-compatible validation error codes.

type ValIssueCode =
  | 'invalid_type'
  | 'invalid_literal'
  | 'custom'
  | 'invalid_union'
  | 'invalid_union_discriminator'
  | 'invalid_enum_value'
  | 'unrecognized_keys'
  | 'invalid_arguments'
  | 'invalid_return_type'
  | 'invalid_date'
  | 'invalid_string'
  | 'too_small'
  | 'too_big'
  | 'invalid_intersection_types'
  | 'not_multiple_of'
  | 'not_finite';

ValIssueBase

Base interface for all validation issues.

interface ValIssueBase {
  readonly code: ValIssueCode;
  readonly path: ReadonlyArray<string | number>;
  readonly message: string;
}
PropertyTypeDescription
codeValIssueCodeThe error code identifying the issue type
path(string | number)[]Path to the invalid value
messagestringHuman-readable error message

Specific Issue Types

InvalidTypeIssue

Issue for type validation failures.

interface InvalidTypeIssue extends ValIssueBase {
  readonly code: 'invalid_type';
  readonly expected: string;
  readonly received: string;
}

Example:

// When parsing: v.string().parse(123)
{
  code: 'invalid_type',
  expected: 'string',
  received: 'number',
  path: [],
  message: 'Expected string, received number'
}

TooSmallIssue

Issue for values that are too small (strings, numbers, arrays, sets, dates, bigints).

interface TooSmallIssue extends ValIssueBase {
  readonly code: 'too_small';
  readonly type: SizeType;
  readonly minimum: number | bigint;
  readonly inclusive: boolean;
  readonly exact?: boolean | undefined;
}
 
type SizeType = 'string' | 'number' | 'array' | 'set' | 'date' | 'bigint';

Example:

// When parsing: v.string().min(5).parse('hi')
{
  code: 'too_small',
  type: 'string',
  minimum: 5,
  inclusive: true,
  path: [],
  message: 'String must be at least 5 characters'
}

TooBigIssue

Issue for values that are too big.

interface TooBigIssue extends ValIssueBase {
  readonly code: 'too_big';
  readonly type: SizeType;
  readonly maximum: number | bigint;
  readonly inclusive: boolean;
  readonly exact?: boolean | undefined;
}

Example:

// When parsing: v.number().max(100).parse(150)
{
  code: 'too_big',
  type: 'number',
  maximum: 100,
  inclusive: true,
  path: [],
  message: 'Value must be at most 100'
}

InvalidStringIssue

Issue for invalid string format.

interface InvalidStringIssue extends ValIssueBase {
  readonly code: 'invalid_string';
  readonly validation:
    | StringValidation
    | { readonly includes: string; readonly position?: number }
    | { readonly startsWith: string }
    | { readonly endsWith: string };
}
 
type StringValidation =
  | 'email'
  | 'url'
  | 'emoji'
  | 'uuid'
  | 'cuid'
  | 'cuid2'
  | 'ulid'
  | 'regex'
  | 'datetime'
  | 'ip'
  | 'base64';

Example:

// When parsing: v.string().email().parse('not-an-email')
{
  code: 'invalid_string',
  validation: 'email',
  path: [],
  message: 'Invalid email'
}

InvalidEnumValueIssue

Issue for enum validation failures.

interface InvalidEnumValueIssue extends ValIssueBase {
  readonly code: 'invalid_enum_value';
  readonly options: ReadonlyArray<string | number>;
  readonly received: unknown;
}

Example:

// When parsing: v.enum(['red', 'green', 'blue']).parse('yellow')
{
  code: 'invalid_enum_value',
  options: ['red', 'green', 'blue'],
  received: 'yellow',
  path: [],
  message: 'Invalid enum value. Expected "red" | "green" | "blue", received "yellow"'
}

InvalidUnionIssue

Issue for union validation failures.

interface InvalidUnionIssue extends ValIssueBase {
  readonly code: 'invalid_union';
  readonly unionErrors: ReadonlyArray<ValError>;
}

InvalidUnionDiscriminatorIssue

Issue for discriminated union validation failures.

interface InvalidUnionDiscriminatorIssue extends ValIssueBase {
  readonly code: 'invalid_union_discriminator';
  readonly options: ReadonlyArray<string | number>;
}

UnrecognizedKeysIssue

Issue for unrecognized object keys (when using .strict()).

interface UnrecognizedKeysIssue extends ValIssueBase {
  readonly code: 'unrecognized_keys';
  readonly keys: ReadonlyArray<string>;
}

Example:

// When parsing: v.object({ name: v.string() }).strict().parse({ name: 'Alice', extra: true })
{
  code: 'unrecognized_keys',
  keys: ['extra'],
  path: [],
  message: "Unrecognized key(s) in object: 'extra'"
}

InvalidLiteralIssue

Issue for literal value validation failures.

interface InvalidLiteralIssue extends ValIssueBase {
  readonly code: 'invalid_literal';
  readonly expected: unknown;
  readonly received: unknown;
}

CustomIssue

Issue for custom validation failures (from .refine() or .superRefine()).

interface CustomIssue extends ValIssueBase {
  readonly code: 'custom';
  readonly params?: Record<string, unknown> | undefined;
}

NotMultipleOfIssue

Issue for values that are not a multiple of a given number.

interface NotMultipleOfIssue extends ValIssueBase {
  readonly code: 'not_multiple_of';
  readonly multipleOf: number;
}

NotFiniteIssue

Issue for non-finite number values.

interface NotFiniteIssue extends ValIssueBase {
  readonly code: 'not_finite';
}

InvalidDateIssue

Issue for invalid Date values.

interface InvalidDateIssue extends ValIssueBase {
  readonly code: 'invalid_date';
}

InvalidArgumentsIssue

Issue for invalid function arguments.

interface InvalidArgumentsIssue extends ValIssueBase {
  readonly code: 'invalid_arguments';
  readonly argumentsError: ValError;
}

InvalidReturnTypeIssue

Issue for invalid function return type.

interface InvalidReturnTypeIssue extends ValIssueBase {
  readonly code: 'invalid_return_type';
  readonly returnTypeError: ValError;
}

InvalidIntersectionTypesIssue

Issue for intersection type validation failures.

interface InvalidIntersectionTypesIssue extends ValIssueBase {
  readonly code: 'invalid_intersection_types';
}

Error Formatting Types

FormattedError<T>

Type for the nested error format returned by ValError.format().

type FormattedError<T = unknown> = {
  _errors: string[];
} & (T extends object
  ? { [K in keyof T]?: FormattedError<T[K]> }
  : unknown);

Usage:

const error = new ValError([
  { message: 'Required', path: ['user', 'name'], code: 'custom' },
  { message: 'Invalid email', path: ['user', 'email'], code: 'custom' },
]);
 
error.format();
// {
//   _errors: [],
//   user: {
//     _errors: [],
//     name: { _errors: ['Required'] },
//     email: { _errors: ['Invalid email'] },
//   }
// }

FlattenedError<T>

Type for the flattened error format returned by ValError.flatten().

interface FlattenedError<T = unknown> {
  formErrors: string[];
  fieldErrors: T extends object
    ? { [K in keyof T]?: string[] }
    : { [key: string]: string[] };
}

Usage:

const error = new ValError([
  { message: 'Required', path: ['name'], code: 'custom' },
  { message: 'Form-level error', path: [], code: 'custom' },
]);
 
error.flatten();
// {
//   formErrors: ['Form-level error'],
//   fieldErrors: {
//     name: ['Required'],
//   }
// }

Error Map Types

ErrorMapFn

Function type for custom error messages.

type ErrorMapFn = (issue: ValIssue, ctx: ErrorMapContext) => string;

ErrorMapContext

Context provided to error map functions.

interface ErrorMapContext {
  readonly defaultError: string;
  readonly data: unknown;
}

Usage:

import { v } from 'valrs';
 
v.setErrorMap((issue, ctx) => {
  if (issue.code === 'invalid_type') {
    return `Expected ${issue.expected}, got ${issue.received}`;
  }
  if (issue.code === 'too_small' && issue.type === 'string') {
    return `Must be at least ${issue.minimum} characters`;
  }
  return ctx.defaultError;
});

Standard Schema Types

StandardSchemaV1

The core Standard Schema interface that all valrs schemas implement.

interface StandardSchemaV1<Input = unknown, Output = Input> {
  readonly '~standard': {
    readonly version: 1;
    readonly vendor: string;
    readonly validate: (
      value: unknown
    ) => ValidationResult<Output> | Promise<ValidationResult<Output>>;
  };
}

StandardJSONSchemaV1

Extended interface for schemas that support JSON Schema generation.

interface StandardJSONSchemaV1<Input = unknown, Output = Input>
  extends StandardSchemaV1<Input, Output> {
  readonly '~standard': StandardSchemaV1<Input, Output>['~standard'] & {
    readonly jsonSchema: {
      readonly input: (options: JsonSchemaOptions) => Record<string, unknown>;
      readonly output: (options: JsonSchemaOptions) => Record<string, unknown>;
    };
  };
}

ValidationResult

The result of a validation operation. A discriminated union based on the presence of issues.

type ValidationResult<T> =
  | { readonly value: T; readonly issues?: undefined }
  | { readonly issues: ReadonlyArray<ValidationIssue>; readonly value?: undefined };

Success case: Contains value of type T, issues is undefined Failure case: Contains issues array, value is undefined


ValidationIssue

Describes why validation failed (Standard Schema format).

interface ValidationIssue {
  readonly message: string;
  readonly path?: ReadonlyArray<PathSegment>;
}
PropertyTypeDescription
messagestringHuman-readable error message
pathPathSegment[]Path to the invalid value (optional)

PathSegment

A segment in a validation issue path.

type PathSegment = string | number | { readonly key: string | number };

Examples:

  • 'name' - String property key
  • 0 - Array index
  • { key: 'special.key' } - Object with explicit key property

JsonSchemaOptions

Options passed to JSON Schema generation functions.

interface JsonSchemaOptions {
  readonly target: string;
}
PropertyTypeDescription
targetstringTarget format: 'draft-2020-12', 'draft-07', or 'openapi-3.0'

InferInput

Infer the input type from a Standard Schema.

type InferInput<T extends StandardSchemaV1> =
  T extends StandardSchemaV1<infer I, unknown> ? I : never;

Usage:

import type { InferInput } from 'valrs';
import { StringSchema } from 'valrs';
 
type StringInput = InferInput<typeof StringSchema>;
// string

InferOutput

Infer the output type from a Standard Schema.

type InferOutput<T extends StandardSchemaV1> =
  T extends StandardSchemaV1<unknown, infer O> ? O : never;

Usage:

import type { InferOutput } from 'valrs';
import { StringSchema } from 'valrs';
 
type StringOutput = InferOutput<typeof StringSchema>;
// string

Exports

All types are exported from the main package:

import type {
  // Type inference
  Infer,
  infer,
  input,
  output,
 
  // SafeParse types
  SafeParseResult,
  SafeParseSuccess,
  SafeParseError,
 
  // Issue types
  ValIssueCode,
  ValIssueBase,
  ValIssue,
  InvalidTypeIssue,
  InvalidLiteralIssue,
  CustomIssue,
  InvalidUnionIssue,
  InvalidUnionDiscriminatorIssue,
  InvalidEnumValueIssue,
  UnrecognizedKeysIssue,
  InvalidArgumentsIssue,
  InvalidReturnTypeIssue,
  InvalidDateIssue,
  InvalidStringIssue,
  TooSmallIssue,
  TooBigIssue,
  InvalidIntersectionTypesIssue,
  NotMultipleOfIssue,
  NotFiniteIssue,
  SizeType,
  StringValidation,
 
  // Error formatting
  FormattedError,
  FlattenedError,
  ErrorMapFn,
  ErrorMapContext,
  SchemaErrorOptions,
 
  // Standard Schema types
  StandardSchemaV1,
  StandardJSONSchemaV1,
  ValidationResult,
  ValidationIssue,
  PathSegment,
  JsonSchemaOptions,
  InferInput,
  InferOutput,
} from 'valrs';
 
// ValError is a value export (class)
import { ValError } from 'valrs';