variant
Several object variants; the variant is selected by a tag field (e.g. type). Unlike union, it shows the errors of the selected variant.
Signature
ts
function variant<K extends string, const T extends readonly ObjectSchema[]>(key: K, options: T, msg?: Message): Schema<Infer<T[number]>>Parameters
| Parameter | Type | Description |
|---|---|---|
key | string | Name of the tag field |
options | ObjectSchema[] | object schemas. Each must have the key field — usually a literal |
msg | Message | Custom message for an empty value, a non-object and an unknown variant |
Notes
- The tag is checked against the
keyfield schema of each variant in order; then the whole object is validated by the matching variant. - The tag can be a
literal,oneOforenumOf— their values are listed in the error message. - The unknown-variant error is attached to the tag field:
errors.type. - The result type is a discriminated union: after
if (data.type === 'card')TypeScript knows the fields of that variant.
Error codes
| Code | When | Default message |
|---|---|---|
required | The value or the tag is empty | Required |
object | Not an object | Must be an object |
variant | Unknown tag value | Unknown type, expected one of: {options} |
Example
Payment method
ts
const Payment = variant('type', [
object({ type: literal('card'), number: pipe(string(), length(16)) }),
object({ type: literal('invoice'), inn: pipe(string(), length(10)) }),
]);
validate(Payment, { type: 'card' }).errors; // { number: 'Required' }
validate(Payment, { type: 'cash' }).errors; // { type: 'Unknown type, expected one of: card, invoice' }
const payment = parse(Payment, body);
if (payment.type === 'card') payment.number; // string