Generate JSON-Schemas from typescript classes annotated with decorators.
pnpm add ts-decorator-json-schema-generator reflect-metadata
or
npm install ts-decorator-json-schema-generator reflect-metadata
As this library uses reflections, the reflect-metadata
library is required and has to be imported before anything
else. And include these options in your tsconfig.json
:
"experimentalDecorators": true,
"emitDecoratorMetadata": true
import 'reflect-metadata';
import { generateJsonSchema } from 'ts-decorator-json-schema-generator';
import { MySchema } from './MySchema';
console.log(generateJsonSchema(MySchema));
import {
DependentRequired, JsonSchema, MaxLength, Min, MinLength, Optional, Pattern, Required
} from 'ts-decorator-json-schema-generator';
// This decorator and it's options are optional and
// only a handy shortcut to add some general info to your schema
@JsonSchema({
id: 'https://example.com/my-schema.schema.json',
title: 'Example Schema',
description: 'An example schema for showcasing some features of the ts-decorator-json-schema-generator library'
})
export class MySchema {
// Primitive types are automatically extracted from the typescript type
@Required()
@Min(0)
public myRequiredNumber!: number;
@Required()
@MinLength(4)
@MaxLength(16)
@Pattern(/^[a-zA-Z_]+$/)
public username!: string;
@Optional()
public streetAddress?: string;
@Optional()
@DependentRequired('streetAddress')
public extendedAddress?: string;
}
Important: Every property has to have at least one decorator (just add Required
or Optional
everywhere) or it won't
be possible to extract the typescript type and include the property in the schema.
- Almost all current json schema validation types are implemented as decorators (currently missing most of the core
structure types like
"if"
/"then"
and more) - You can set the type to another schema typescript class to include a subschema.
- Explicitly set the property type with @Type which accepts a type name or another schema class ->
@Type("integer")
or@Type(OtherSchema)
. @Enum
accepts typescript enums and automatically sets the correct accepted values and property type.
JSON schema keyword | Decorator | Description |
---|---|---|
Common schema decorators | ||
$id, title, description, $schema | @JsonSchema({ id?: string; title?: string; description?: string }) |
Used on a class to mark it as a json schema class. Pass the options object to set metadata on the json schema |
$comment | ❌ | |
type | @Type(typeNameOrSchemaClass: string | ClassConstructor) |
Explicitly set the type of this property to either a subschema class or a type name (one of string , number , integer , boolean , object , array , null ) |
enum | @Enum(enumClass: Enum, valueType?: 'string' | 'number' | 'integer') |
Use a TypeScript enum class to set enum values on this property. The decorator tries to guess if your enum contains string or number types to set the type on the schema of the property, but this can be explicitly set with valueType |
const | ❌ | The const keyword is used to restrict a value to a single value. |
dependentRequired | @DependentRequired(...requiredProperties: string[]) |
List all other property keys, which this property depends on. |
dependentSchemas | ❌ | |
default | @Default(value: any) |
Set a default value for a property. This might be used by documentation generators. |
examples | @Examples(examples: any[]) |
Provide a list of example values for this property. This might be used by documentation generators. |
readOnly | @ReadOnly() |
Mark a property as read-only. |
writeOnly | @WriteOnly() |
Mark a property as write-only. |
deprecated | @Deprecated() |
Mark a property as deprecated. |
$ref | See subschemas | |
Composition decorators | ||
allOf | @AllOf(...schemaOrClasses: ClassConstructor | JSONSchema7) |
|
anyOf | @AnyOf(...schemaOrClasses: ClassConstructor | JSONSchema7) |
|
oneOf | @OneOf(...schemaOrClasses: ClassConstructor | JSONSchema7) |
|
not | @Not(schemaOrClass: ClassConstructor | JSONSchema7) |
|
String decorators | ||
minLength | @MaxLength(maxLength: number) |
Set the max length of this string. |
maxLength | @MinLength(minLength: number) |
Set the min length of this string. |
pattern | @Pattern(pattern: RegExp | string) |
Require the string to match the given RegExp pattern. |
format | @Format(format: string) |
Json schemas have a list of inbuilt string formats for strings containing dates, email addresses and more. |
contentEncoding | @ContentEncoding(contentEncoding: string) |
Specify the encoding of the content of this string. Examples include base16 , base32 , base32hex base64 . |
contentMediaType | @ContentMediaType(mimeType: string) |
Specify the mimetype of the content of this string. |
contentSchema | @ContentSchema(schemaClass: ClassConstructor) |
Specify the json schema, which the content of this string should adhere to. |
Number decorators | ||
minimum | @Min(min: number) |
Set the min value of the number. |
maximum | @Max(max: number) |
Set the max value of the number. |
minimum and maximum | @Range(min: number, max: number) |
Shortcut for setting both @Min and @Max. |
exclusiveMin | @ExclusiveMin(exclusiveMin: number) |
Set the exclusive min value of the number. |
exclusiveMax | @ExclusiveMax(exclusiveMax: number) |
Set the exclusive max value of the number. |
multipleOf | @MultipleOf(value: number) |
Require to the number to be a multiple of value . |
Object decorators | ||
required (on the parent object) | @Required() |
Mark this property as required |
(doesn't set anything) | @Optional() |
Mark this property as optional (no used in json schema, decorator exists for parity with @Required() decorator) |
minProperties | @MinProperties(minAmount: number) |
Require a min amount of properties on this object |
maxProperties | @MaxProperties(maxAmount: number) |
Restrict the max amount of properties on this object |
additionalProperties | ❌ | |
patternProperties | ❌ | |
propertyNames | ❌ | |
Array decorators | ||
items | @Items(type: string | ClassConstructor) |
Specify the type for each array item by passing a json schema type or a class |
contains | @Items(type: string | ClassConstructor) |
Specify the type for each array item by passing a json schema type or a class |
minItems | @MinItems(minAmount: number) |
Require a min amount of items in this array |
maxItems | @MaxItems(maxAmount: number) |
Restrict the max amount of items in this array |
uniqueItems | @UniqueItems() |
Require each array item to be unique |
Conditional decorators | ||
if/then/else | ❌ |
When your schema classes have properties, which are also schema classes, there are different ways to place the subschemas of these classes into the final json schema.
The generateJsonSchema(sourceClass: ClassConstructor, options?: SchemaGeneratorOptions)
method accepts an options
object, where you can set includeSubschemas
to the following values:
Value | Description |
---|---|
full |
Basically "copy-pastes" the full class json-schema into the property type |
anonymously |
Like full , but removes the $id field to resolve problems with having json-schemas with the same $id defined multiple times in a file |
reference |
Inserts a $ref to the json-schema $id, which then has to be resolved by the system loading the json-schemas. |
($id: string | undefined) => SubschemaIncludeType |
Decide for each subschema, how to insert it. |
Similar libraries are ts-json-schema-generator, which uses JSDoc comments for information on how to build the json schema instead of decorators and requires the source .ts files to be present. There is also ts-json-schema-decorator, which uses decorators and inspired this library, but I decided to write a completely new library instead of forking this project, as the code looked very hard to maintain. Furthermore, it used an unusual approach when it comes to generating the json schema, as the decorators "magically" generated the schema when a class with the correct decorator was loaded, and appended the generated schema to the class prototype.