Parse data

Now that you've learned how to create a schema, let's look at how you can use it to validate unknown data and make it type-safe. I offer 3 different ways for this. Just pick what you think fits your code best.

Each schema has a ._parse method. However, this is an internal API and should only be used if you know what you are doing.

Default way

The parse method will throw a ValiError if the input does not match the schema. Therefore you should use a try/catch block to catch errors. If the input matches the schema, it is valid and the output of the schema will be returned typed.

import * as v from 'valibot';

try {
  const EmailSchema = v.string([v.email()]);
  const email = v.parse(EmailSchema, 'jane@example.com');

  // Handle errors if one occurs
} catch (error) {
  console.log(error);
}

Safe parse

If you want issues to be returned instead of thrown, you can use safeParse. The returned value then contains the .success property, which is true if the input is valid or false otherwise.

If the input is valid, you can use .output to get the output of the schema validation. On the other hand, if the input was invalid, the issues found can be accessed via .issues.

import * as v from 'valibot';

const EmailSchema = v.string([v.email()]);
const result = v.safeParse(EmailSchema, 'jane@example.com');

if (result.success) {
  const email = result.output;
} else {
  console.log(result.issues);
}

Type guards

Another way to validate data that can be useful in individual cases is to use a type guard. A type guard is an if-condition which, if true, sets the parsed data to the input type of a schema.

If a type guard is used, the issues of the validation cannot be accessed. Also, transformations have no effect and unknown keys of an object are not removed. Therefore, this approach is not as safe and powerful as the two previous ways. Also, due to a TypeScript limitation, it can currently only be used with synchronous schemas.

import * as v from 'valibot';

const EmailSchema = v.string([v.email()]);
const data: unknown = 'jane@example.com';

if (v.is(EmailSchema, data)) {
  const email = data; // string
}

Configuration

By default, I collect each issue during validation to give you detailed feedback on why the input does not match the schema. If this is not required in your use case, you can control this behavior with abortEarly, abortPipeEarly and skipPipe to improve the performance of validation.

Abort validation

If you set abortEarly to true I immediately abort the validation after finding a first issue. If you just want to know if data matches a schema, but you don't care about the details, this can speed up the performance.

import * as v from 'valibot';

try {
  const ProfileSchema = v.object({
    name: v.string(),
    bio: v.string(),
  });
  const profile = v.parse(
    ProfileSchema,
    { name: 'Jane', bio: '' },
    { abortEarly: true }
  );

  // Handle errors if one occurs
} catch (error) {
  console.log(error);
}

Abort pipeline

If you only set abortPipeEarly to true I only abort the validation within a pipeline after I found a first issue. For example, if you want to show only the first error of a field when validating a form, you can use this option to speed up the performance of validation.

import * as v from 'valibot';

try {
  const EmailSchema = v.string([v.email(), v.endsWith('@example.com')]);
  const email = v.parse(EmailSchema, 'jane@example.com', {
    abortPipeEarly: true,
  });

  // Handle errors if one occurs
} catch (error) {
  console.log(error);
}

Skip pipeline

If you set skipPipe to true I skip every pipeline of a schema. This can be useful for forms, for example, to check only the data types of initial values and not the other details that are validated in the pipelines.

import * as v from 'valibot';

try {
  const EmailSchema = v.string([v.email(), v.endsWith('@example.com')]);
  const email = v.parse(EmailSchema, '', { skipPipe: true });

  // Handle errors if one occurs
} catch (error) {
  console.log(error);
}

Contributors

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

  • GitHub profile picture of fabian-hiller
  • GitHub profile picture of cmaciasjimenez

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 dailydotdev
  • GitHub profile picture of ivan-mihalic
  • GitHub profile picture of KATT
  • GitHub profile picture of osdiab
  • GitHub profile picture of Thanaen
  • GitHub profile picture of ruiaraujo012
  • GitHub profile picture of hyunbinseo
  • GitHub profile picture of caegdeveloper