Optionals
It often happens that undefined
or null
should also be accepted instead of the value. To make the API more readable for this and to reduce boilerplate, I offer a shortcut for this functionality with optional
, nullable
, nullish
and undefinedable
.
How it works
To accept undefined
or null
besides your actual value, you just have to wrap the schema in optional
, nullable
, and undefinedable
.
import * as v from 'valibot';
const OptionalStringSchema = v.optional(v.string()); // string | undefined
const NullableStringSchema = v.nullable(v.string()); // string | null
const NullishStringSchema = v.nullish(v.string()); // string | null | undefined
const UndefinedableStringSchema = v.undefinedable(v.string()); // string | undefined
Use in objects
When used inside of objects, optional
and nullish
is a special case, as it also marks the value as optional in TypeScript with a question mark.
import * as v from 'valibot';
const OptionalKeySchema = v.object({ key: v.optional(v.string()) }); // { key?: string | undefined }
Default values
The special thing about optional
, nullable
, nullish
and undefinedable
is that the schema functions accept a default value as the second argument. Depending on the schema function, this default value is always used if the input is undefined
or null
.
import * as v from 'valibot';
const OptionalStringSchema = v.optional(v.string(), "I'm the default!");
type OptionalStringInput = v.Input<typeof OptionalStringSchema>; // string | undefined
type OptionalStringOutput = v.Output<typeof OptionalStringSchema>; // string
By providing a default value, the input type of the schema now differs from the output type. The schema in the example now accepts string
and undefined
as input, but returns a string as output in both cases.
Dynamic values
In some cases it is necessary to generate the default value dynamically. For this purpose, a function that generates and returns the default value can also be passed as the second argument.
import * as v from 'valibot';
const NullableDateSchema = v.nullable(v.date(), () => new Date());
The previous example thus creates a new instance of the Date
class for each validation with null
as input, which is then used as the default value.