Skip to Content
@jetio/schema-builder docs are live 🎉

Arrays

Homogeneous arrays (items)

Draft 2019-09 and above. All elements share a type.

const tagsSchema = new SchemaBuilder() .array() .items((s) => s.string()) .build(); type Tags = Jet.Infer<typeof tagsSchema>; // string[] const usersSchema = new SchemaBuilder() .array() .items((s) => s .object() .properties({ id: (s) => s.number(), name: (s) => s.string(), }) .required(["id", "name"]), ) .build(); type Users = Jet.Infer<typeof usersSchema>; // { id: number; name: string }[] const matrixSchema = new SchemaBuilder() .array() .items((s) => s.array().items((s) => s.number())) .build(); type Matrix = Jet.Infer<typeof matrixSchema>; // number[][]

Tuples with prefixItems

Draft 2020-12. Fixed positions, each with its own type.

const coordinateSchema = new SchemaBuilder() .array() .prefixItems( (s) => s.number(), // latitude (s) => s.number(), // longitude ) .build(); type Coordinate = Jet.Infer<typeof coordinateSchema>; // [number, number] const recordSchema = new SchemaBuilder() .array() .prefixItems( (s) => s.string(), (s) => s.number(), (s) => s.boolean(), (s) => s.null(), ) .build(); type Record = Jet.Infer<typeof recordSchema>; // [string, number, boolean, null] const userActionSchema = new SchemaBuilder() .array() .prefixItems( (s) => s.string(), // action type (s) => s.object() .properties({ userId: (s) => s.number(), timestamp: (s) => s.number() }) .required(['userId', 'timestamp']) ) .build(); type UserAction = Jet.Infer<typeof userActionSchema>; // Result: [string, { userId: number; timestamp: number }]

Tuples with rest elements

Combine .prefixItems() with .items() for a fixed prefix plus variable rest.

const featureSchema = new SchemaBuilder() .array() .prefixItems( (s) => s.string(), // feature name (s) => s.number(), // version number ) .items((s) => s.boolean()) // ...feature flags .build(); type Feature = Jet.Infer<typeof featureSchema>; // [string, number, ...boolean[]] // More complex example with object rest elements const logEntrySchema = new SchemaBuilder() .array() .prefixItems( (s) => s.string(), // log level (s) => s.number() // timestamp ) .items((s) => s.object() .properties({ key: (s) => s.string(), value: (s) => s.string() }) .required(['key', 'value']) ) .build(); type LogEntry = Jet.Infer<typeof logEntrySchema>; // Result: [string, number, ...{ key: string; value: string }[]]

Tuples with items (Draft 07 and below)

In older drafts, array-form .items() defines the tuple and .additionalItems() defines the rest.

const coordinateSchema = new SchemaBuilder() .array() .items( (s) => s.number(), (s) => s.number(), ) .build(); type Coordinate = Jet.Infer<typeof coordinateSchema>; // [number, number] const featureSchema = new SchemaBuilder() .array() .items( (s) => s.string(), (s) => s.number(), ) .additionalItems((s) => s.boolean()) .build(); type Feature = Jet.Infer<typeof featureSchema>; // [string, number, ...boolean[]]

Array constraints

const limitedArraySchema = new SchemaBuilder() .array() .items((s) => s.string()) .minItems(2) .maxItems(5) .uniqueItems(true) .build(); type LimitedArray = Jet.Infer<typeof limitedArraySchema>; // string[]

minItems, maxItems, and uniqueItems are enforced at runtime but don’t appear in the type — TypeScript can’t express “array of length 2–5”.

Last updated on