Objects

To validate objects with a schema, you can use object or record. You use object for an object with a specific shape and record for objects with any number of uniform entries.

Object schema

The first argument is used to define the specific structure of the object. Each entry consists of a key and a schema as the value. The entries of the input are then validated against these schemas.

import * as v from 'valibot';

const ObjectSchema = v.object({
  key1: v.string(),
  key2: v.number(),
});

Loose and strict objects

The object schema removes unknown entries. This means that entries that you have not defined in the first argument are not validated and added to the output. You can change this behavior by using the looseObject or strictObject schema instead.

The looseObject schema allows unknown entries and adds them to the output. The strictObject schema forbids unknown entries and returns an issue for the first unknown entry found.

Object with specific rest

Alternatively, you can also use the objectWithRest schema to define a specific schema for unknown entries. Any entries not defined in the first argument are then validated against the schema of the second argument.

import * as v from 'valibot';

const ObjectSchema = v.objectWithRest(
  {
    key1: v.string(),
    key2: v.number(),
  },
  v.null()
);

Pipeline validation

To validate the value of an entry based on another entry, you can wrap you schema with the check validation action in a pipeline. You can also use forward to assign the issue to a specific object key in the event of an error.

If you only want to validate specific entries, I recommend using partialCheck instead as check can only be executed if the input is fully typed.

import * as v from 'valibot';

const CalculationSchema = v.pipe(
  v.object({
    a: v.number(),
    b: v.number(),
    sum: v.number(),
  }),
  v.forward(
    v.check(({ a, b, sum }) => a + b === sum, 'The calculation is incorrect.'),
    ['sum']
  )
);

Record schema

For an object with any number of uniform entries, record is the right choice. The schema passed as the first argument validates the keys of your record, and the schema passed as the second argument validates the values.

import * as v from 'valibot';

const RecordSchema = v.record(v.string(), v.number()); // Record<string, number>

Specific record keys

Instead of string, you can also use custom, enum, literal, picklist or union to validate the keys.

import * as v from 'valibot';

const RecordSchema = v.record(v.picklist(['key1', 'key2']), v.number()); // { key1?: number; key2?: number }

Note that record marks all literal keys as optional in this case. If you want to make them required, you can use the object schema with the entriesFromList util instead.

import * as v from 'valibot';

const RecordSchema = v.object(v.entriesFromList(['key1', 'key2'], v.number())); // { key1: number; key2: number }

Pipeline validation

To validate the value of an entry based on another entry, you can wrap you schema with the check validation action in a pipeline. You can also use forward to assign the issue to a specific record key in the event of an error.

import * as v from 'valibot';

const CalculationSchema = v.pipe(
  v.record(v.picklist(['a', 'b', 'sum']), v.number()),
  v.forward(
    v.check(
      ({ a, b, sum }) => (a || 0) + (b || 0) === (sum || 0),
      'The calculation is incorrect.'
    ),
    ['sum']
  )
);

Contributors

Thanks to all the contributors who helped make this page better!

  • GitHub profile picture of fabian-hiller
  • GitHub profile picture of Mini-ghost

Partners

Thanks to our partners who support the project ideally and financially.

Sponsors

Thanks to our GitHub sponsors who support the project financially.

  • GitHub profile picture of Thanaen
  • GitHub profile picture of KATT
  • GitHub profile picture of osdiab
  • GitHub profile picture of ruiaraujo012
  • GitHub profile picture of hyunbinseo
  • GitHub profile picture of F0rce
  • GitHub profile picture of caegdeveloper
  • GitHub profile picture of luckasnix