Validation modes
json-tology enforces schema constraints at two layers: the TypeScript compiler and the runtime validator. Each documented feature carries a badge that identifies which layer (or layers) catches a violation.
Badge reference
| Badge | Meaning |
|---|---|
| Compile-time | The TypeScript compiler rejects the violation. Data that fails this check never compiles - the bug is caught before the program runs. |
| Runtime | The validator catches the violation when untrusted data enters the system - at instantiate, validate, is, materialize, or cast. |
| Compile-time + Runtime | Both layers enforce the constraint. The compiler blocks authoring mistakes; the runtime validator guards the trust boundary for data from external sources. |
Why both layers?
The two layers cover different failure modes:
- Compile-time catches programmer mistakes - passing the wrong type to a function, violating a schema constraint in code you control.
- Runtime catches data quality failures - untrusted input from APIs, files, user-submitted forms, or messages that may not respect the schema.
Ideal keyword coverage is Compile-time + Runtime: the compiler prevents in-process mistakes, and the runtime validator guards external boundaries.
Some constraints are Compile-time only - they express TypeScript-level invariants that have no equivalent runtime check (e.g. $id nominal brands: two schemas with the same structure but different $id values produce incompatible TypeScript types; at runtime they validate identically).
Some constraints are Runtime only - they require value inspection that happens after data arrives (e.g. cross-schema $ref resolution, uniqueness of array element values beyond tuple literal narrowing).
Where badges appear
Badges appear inline next to each documented keyword, brand, or feature in the reference pages. When a feature section covers a constraint, the badge appears at the heading or in the table entry, as shown here:
## `format` <Badge type="warning" text="Compile-time + Runtime" />Cross-referencing
The enforcement layer for every keyword in the standard JSON Schema 2020-12 vocabulary:
| Keyword | Layer |
|---|---|
type | Compile-time + Runtime |
required | Compile-time + Runtime |
properties | Compile-time + Runtime |
enum | Compile-time + Runtime |
const | Compile-time + Runtime |
format | Compile-time + Runtime |
pattern | Compile-time + Runtime |
minLength / maxLength | Compile-time + Runtime |
minimum / maximum | Compile-time + Runtime |
exclusiveMinimum / exclusiveMaximum | Compile-time + Runtime |
multipleOf | Compile-time + Runtime |
minItems / maxItems | Compile-time + Runtime |
uniqueItems | Compile-time + Runtime |
allOf / anyOf / oneOf / not | Compile-time + Runtime |
if / then / else | Compile-time + Runtime |
dependentRequired / dependentSchemas | Compile-time + Runtime |
patternProperties | Compile-time + Runtime |
additionalProperties: false | Compile-time + Runtime |
$ref (local fragment) | Compile-time + Runtime |
$ref (cross-schema) | Compile-time + Runtime |
$id nominal brand | Compile-time |
$schema dialect brand | Compile-time |
disjointWith | Compile-time + Runtime |
complementOf | Compile-time (runtime not constraint applies via the emitted not: { $ref } wire shape; no custom registry check) |
OWL property restrictions (jt:restrictions) | Compile-time |
| OWL property characteristics | Runtime |
Compose.pick / Compose.omit key validity | Compile-time |
Compose.discriminatedUnion discriminator presence | Compile-time |
Compose.subClassOf self-subclass prevention | Compile-time |
Compose.equivalent self-equivalence prevention | Compile-time |
Compose.intersection ID collision prevention | Compile-time |
Transform.chain stage chain compatibility | Compile-time |
Schema cross-keyword validation (ValidateSchemaType) | Compile-time |
Related
- Constraint brands - phantom brands for every constraint keyword
- Schemas - standard keyword authoring
- Migration to 0.4.0 - breaking changes in this release