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
By default, if you use parse
or parseAsync
, a ValiError
is thrown if the input does not match the schema. Therefore you should use a try/catch block to catch the error. If the input matches the schema, it is valid and the output of the schema will be returned typed.
import { email, parse, string } from 'valibot'; // 0.63 kB
try {
const EmailSchema = string([email()]);
const email = 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
or safeParseAsync
. 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 { email, safeParse, string } from 'valibot'; // 0.66 kB
const EmailSchema = string([email()]);
const result = 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, it can currently only be used with syncronous schemas.
import { email, is, string } from 'valibot'; // 0.55 kB
const EmailSchema = string([email()]);
const data: unknown = 'jane@example.com';
if (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
.
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 { object, parse, string } from 'valibot'; // 0.72 kB
try {
const ProfileSchema = object({
name: string(),
bio: string(),
});
const profile = 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 { email, endsWith, parse, string } from 'valibot'; // 0.66 kB
try {
const EmailSchema = string([email(), endsWith('@example.com')]);
const email = 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 { email, endsWith, parse, string } from 'valibot'; // 0.66 kB
try {
const EmailSchema = string([email(), endsWith('@example.com')]);
const email = parse(EmailSchema, '', { skipPipe: true });
// Handle errors if one occurs
} catch (error) {
console.log(error);
}