Skip to content

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 ​

ParameterTypeDescription
keystringName of the tag field
optionsObjectSchema[]object schemas. Each must have the key field — usually a literal
msgMessageCustom message for an empty value, a non-object and an unknown variant

Notes ​

  • The tag is checked against the key field schema of each variant in order; then the whole object is validated by the matching variant.
  • The tag can be a literal, oneOf or enumOf — 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 ​

CodeWhenDefault message
requiredThe value or the tag is emptyRequired
objectNot an objectMust be an object
variantUnknown tag valueUnknown 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

See also ​