Combining schemas to model real-world shapes
allOf — intersection
The instance must validate against every sub-schema. Use this for inheritance-like composition: 'is a Base AND has these extra fields.'
anyOf — union (at least one)
The instance must validate against at least one sub-schema. Use this for fuzzy/loose unions: 'string or number,' 'one of several optional shapes.'
oneOf — exclusive union (exactly one)
The instance must validate against exactly one sub-schema. Use this for tagged unions: 'either a payment with credit_card details OR a payment with bank_transfer details, never both.'
not — negation
The instance must NOT validate against the sub-schema. Use sparingly — error messages on not are notoriously vague. Better to express the constraint positively when possible.
Tagged-union pattern: for polymorphic data ('one of N variants'), prefer
oneOf with a discriminating field (kind, type) checked via const. Validators give clear error messages when one variant matches; anyOf obscures which variant the user intended.