Internal
Types have an extremely powerful internal representation defined in @ark/schema that is primarily exposed through the .internal property on each Type.
Though APIs under .internal are not officially frozen, they are stable enough that we want to start giving users more direct access to some of the introspection capabilities they provide.
Node kinds
All nodes have a kind property indicating their purpose, structure and special properties.
Roots
The kind at the root of a Type will always be one of the following root kind.
Bases
The simplest root nodes are defined by a single basis constraint.
Only a single basis can exist in an intersection. From widest to narrowest:
| kind | description | example |
|---|---|---|
domain | One of 5 non-enumerable type sets ( | { domain: "string" } |
proto | A constructor checked by | { proto: Date } |
unit | An exact value checked by | { unit: true } |
Composites
Root kinds are built from references to other nodes.
Will be normalized to appear in approximately the following hierarchical order:
| kind | description | example |
|---|---|---|
alias | Stores a cyclic reference to a node | { reference: "$name" } |
union | A set of allowed nodes | { branches: ["string", "Array"] } |
morph | One or more transformations applied to valid data | { in: "string", morphs: [(s) => s.trim()] } |
intersection | An intersection of constraints | { domain: "number", divisor: 5 } |
Constraints
Constraint nodes exist on an intersection (or its structure) and narrow the set of values allowed by its basis.
Refinements
Primitive constraints that apply to the data shallowly.
| kind | impliedBasis | description | example |
|---|---|---|---|
divisor | number | Multiple of the specified integer | { rule: 2 } |
pattern | string | Matched by a regex | { rule: "^[a-z]+$" } |
min | number | Numeric minimum (inclusive by default) | { rule: 0, exclusive: true } |
max | number | Numeric maximum (inclusive by default) | { rule: 100 } |
minLength | string | Array | Inclusive minimum length | { rule: 1 } |
maxLength | string | Array | Inclusive maximum length | { rule: 255 } |
exactLength | string | Array | Exact length | { rule: 10 } |
after | Date | Minimum Date (inclusive by default) | { rule: new Date("2000-01-01") } |
before | Date | Maximum Date (inclusive by default) | { rule: new Date() } |
predicate | unknown | Custom narrow function | { predicate: (n) => n % 2 === 1 } |
Structural
These constraints define the shape and properties of objects or arrays.
| kind | description | example |
|---|---|---|
sequence | Defines array patterns with tuples, rest elements, and variadic parts | { sequence: { prefix: ["string", "number"] } } |
required | Defines a required property in an object structure | { key: "id", value: "number" } |
optional | Defines an optional property in an object structure | { key: "name", value: "string" } |
index | Defines index signatures for objects (
| { key: "string", value: "boolean" } |
More details on the type system to come!
select
select is not fully stable!
select relies on the internal representation defined in @ark/schema, which although relatively mature, is not guaranteed semver-stable.
select is the top-level first method we're introducing for interacting with a Type based on its internal representation.
It can be used to filter a Type's references: