Skip to content

Schemas ​

Juniper classJSON SchemaTypeScript
ArraySchematype: 'array'unknown[]
BooleanSchematype: 'boolean'boolean
CustomSchemaWhatever is providedWhatever is provided
EnumSchemaenum: []Union of the provided literals
MergeSchemaNone (compositional)unknown, then | or & as appropriate
NeverSchemanot: {}never
NullSchematype: 'null'null
NumberSchematype: 'number' or type: 'integer'number
ObjectSchematype: 'object'{}
StringSchematype: 'string'string
TupleSchematype: 'array'[unknown]
  • There is no any schema. Use MergeSchema for unknown. If any is truly required, use CustomSchema, whose default output is an always-valid empty schema.
  • In the tables below, Constructor parameter means the keyword can be passed to the constructor as well as set with its method. Can be unset means the method accepts undefined to remove it. Changes types means it narrows the inferred TypeScript type.

Generic schema methods ​

Available on every schema, except where the result would be nonsensical (for example, EnumSchema can't be nullable). All methods return a new instance.

MethodConstructor parameterCan be unsetChanges types
title✅✅❌
description✅✅❌
default✅✅❌
deprecated✅✅❌
example(s)❌❌❌
readOnly✅✅❌
writeOnly✅✅❌
allOf❌❌✅
anyOf❌❌✅
oneOf❌❌✅
not❌❌✅
if then else❌❌✅
nullable❌❌✅

not(schema) rejects everything schema accepts, including null when schema is nullable. To make a nullable schema non-nullable, pass nullSchema():

ts
import { 
nullSchema
,
stringSchema
} from 'juniper';
// string, emitted as { type: 'string' } const
name
=
stringSchema
().
nullable
().
not
(
nullSchema
());

By contrast, .not(stringSchema().nullable()) rejects every string as well as null, so nothing passes.

ArraySchema ​

Represents type: 'array'. TypeScript type: unknown[].

MethodConstructor ParameterCan be UnsetChanges TypesOpenAPI 3.0
items✅❌✅✅
maxItems✅✅❌✅
minItems✅✅✅✅
uniqueItems✅✅❌✅
contains❌❌✅❌
maxContains✅✅❌❌
minContains✅✅❌❌
(prepend)prefixItem❌❌✅❌

minItems up to 3 makes those items required in the type, so an empty array is rejected where the schema rejects it:

ts
import { 
arraySchema
,
stringSchema
, type
SchemaType
} from 'juniper';
const
tags
=
arraySchema
(
stringSchema
()).
minItems
(1);
type
Tags
=
SchemaType
<typeof
tags
>;
type Tags = [string, ...string[]]

Larger values, or a number variable, leave the type as an array. To build a value from an array of unknown length, narrow it first, as a length check alone does not:

ts
const 
isNonEmpty
= <
T
>(
array
:
T
[]):
array
is [
T
, ...
T
[]] =>
array
.
length
> 0;

EnumSchema ​

Represents enum: []. TypeScript type: union of provided literals.

MethodConstructor ParameterCan be UnsetChanges TypesOpenAPI 3.0
enum(s)✅❌✅✅

NumberSchema ​

Represents type: 'number' or type: 'integer'. TypeScript type: number.

MethodConstructor ParameterCan be UnsetChanges TypesOpenAPI 3.0
type✅✅❌✅
multipleOf✅❌❌✅
maximum✅✅❌✅
exclusiveMaximum✅✅❌✅
minimum✅✅❌✅
exclusiveMinimum✅✅❌✅

ObjectSchema ​

Represents type: 'object'. TypeScript type: {}.

MethodConstructor ParameterCan be UnsetChanges TypesOpenAPI 3.0
properties✅✅✅✅
maxProperties✅✅❌✅
minProperties✅✅❌✅
required✅✅✅✅
additionalProperties✅✅✅✅
patternProperties❌✅✅❌
dependentRequired❌❌✅✅
dependentSchemas❌❌✅✅
unevaluatedProperties✅❌❌❌

Note on additionalProperties: JSON Schema interprets omitting additionalProperties as additionalProperties: true. The emitted TypeScript type includes the index signature only when additionalProperties is explicitly set to true:

ts
import { 
objectSchema
, type
SchemaType
} from 'juniper';
const
empty
=
objectSchema
();
type
EmptyObject
=
SchemaType
<typeof
empty
>;
type EmptyObject = {
    [emptyObject]?: never;
}
const
indexed
=
empty
.
additionalProperties
(true);
type
IndexedObject
=
SchemaType
<typeof
indexed
>;
type IndexedObject = {
    [x: string]: unknown;
}

Note on patternProperties: The key is a regular expression pattern and cannot be interpreted directly as a TypeScript string type. Wrap the key with the PatternProperties helper type:

ts
import { 
numberSchema
,
objectSchema
, type
PatternProperties
, type
SchemaType
} from 'juniper';
const
startsOrEndsWith
=
objectSchema
()
.
patternProperties
(
'^abc' as
PatternProperties
<`abc${string}`>,
true ) .
patternProperties
(
'xyz$' as
PatternProperties
<`${string}xyz`>,
numberSchema
()
); type
Output
=
SchemaType
<typeof
startsOrEndsWith
>;
type Output = {
    [x: `abc${string}`]: unknown;
    [x: `${string}xyz`]: number;
}

Discriminated unions: oneOf(schemas, { discriminator: 'kind' }) checks that every branch requires kind as a single, unique string value, and emits OpenAPI's discriminator keyword. See Discriminated unions.

To derive variants of an object schema with pick, omit, partial, required and extend, see Deriving object schemas.

StringSchema ​

Represents type: 'string'. TypeScript type: string.

MethodConstructor ParameterCan be UnsetChanges TypesOpenAPI 3.0
format✅✅❌✅
maxLength✅✅❌✅
minLength✅✅❌✅
pattern✅❌❌✅
startsWith❌❌✅✅
endsWith❌❌✅✅
contains❌❌✅✅
contentEncoding✅✅❌❌
contentMediaType✅✅❌❌

OpenAPI 3.0 has no contentEncoding or contentMediaType, so they are left out of its output. Use format('byte') (base64) or format('binary') instead.

startsWith, endsWith, and contains are wrappers around the pattern property with special TypeScript handling to narrow the inferred string type (e.g. startsWith('abc') produces `abc${string}`).

format autocompletes the formats defined by JSON Schema and OpenAPI 3.0 (date-time, email, uuid, uri, ..., exported as the KnownFormat type), and accepts any other string as a custom format.

TupleSchema ​

Represents type: 'array' with strict tuple semantics. TypeScript type: [unknown]. A convenience wrapper around ArraySchema that prevents editing items directly. Every TupleSchema is an ArraySchema.

MethodConstructor ParameterCan be UnsetChanges TypesOpenAPI 3.0
uniqueItems✅✅❌✅
contains❌❌✅❌
maxContains✅✅❌❌
minContains✅✅❌❌
(prepend)prefixItem❌❌✅❌

BooleanSchema ​

Represents type: 'boolean'. TypeScript type: boolean.

Exposes all generic schema methods. Does not expose not (use EnumSchema to restrict boolean values).

NullSchema ​

Represents type: 'null'. TypeScript type: null.

Exposes all generic schema methods.

NeverSchema ​

Represents not: {}. TypeScript type: never.

Exposes all generic schema methods.

MergeSchema ​

A compositional schema with no inherent type constraint. TypeScript type: unknown initially, narrowed to | or & via anyOf/allOf. Use this for generic unknown types or to combine unrelated schemas.

Exposes all generic schema methods.

CustomSchema ​

Accepts arbitrary JSON Schema content. TypeScript type is provided via the generic parameter.

ts
import { 
customSchema
} from 'juniper';
const
mySchema
=
customSchema
<{
foo
: string }>({
foo
: {
type
: 'string' } });

Use CustomSchema when integrating with pre-existing JSON Schemas or adopting Juniper incrementally. Its use is discouraged in greenfield code.