đź“– Guide Documents
Enhanced JSON
JSON Schema

application() function

export namespace json {
    export function application<
        Schemas extends unknown[],
        Purpose extends "ajv" | "swagger",
    >(): IJsonApplication;
}

JSON schema generator.

When you need JSON schema, do not write it by yourself, but just call typia.application() function.

If you call the typia.application() with specialization of target Schemas, typia will analyze your Schemas and generate JSON schema definition in the compilation level. However, note that, JSON schema definitions of AJV and Swagger are a little bit different. Therefore, you have to consider which value to assign in the Purpose argument.

  • Swagger can't express tuple type
  • Swagger can't express pattern property
examples/src/application.ts
import typia, { tags } from "typia";
 
export const MemberSchema = typia.application<[IMember], "ajv">();
 
interface IMember {
    /**
     * Unique user ID generated by server.
     */
    id: string & tags.Format<"uuid">;
 
    /**
     * Email address of the member.
     */
    email: string & tags.Format<"email">;
 
    /**
     * Age of the member.
     * 
     * For reference, only adult can be a member.
     */
    age: number 
        & tags.Type<"uint32"> 
        & tags.ExclusiveMinimum<19> 
        & tags.Maximum<100>;
}

Specialization

You can utilize type tags (or validator's comment tags) to constructing special fields of JSON schema.

If you write any comment on a property, it would fill the IJsonSchema.description value. Also, there're special comment tags only for JSON schema definition that are different with validator's comment tags like below.

  • @deprecated
  • @hidden
  • @internal
  • @title {string}
  • @default {value}

Let's see how those type tags, comment tags and description comments are working with example code.

examples/src/application-comment-tags.ts
import typia, { tags } from "typia";
 
export const SpecialTagSchema = typia.json.application<[Special], "swagger">();
 
interface Special {
    /**
     * Deprecated tags are just used for marking.
     * 
     * @title Unsigned integer
     * @deprecated
     */
    type: number & tags.Type<"int32">;
 
    /**
     * Internal tagged property never be shown in JSON schema.
     * 
     * It even doesn't be shown in other `typia` functions like `assert<T>()`.
     * 
     * @internal
     */
    internal: number[];
 
    /**
     * Hidden tagged property never be shown in JSON schema.
     * 
     * However, it would be shown in other `typia` functions like `stringify<T>()`.
     * 
     * @hidden
     */
    hidden: boolean;
 
    /**
     * You can limit the range of number.
     * 
     * @exclusiveMinimum 19
     * @maximum 100
     * @default 30
     */
    number?: number;
 
    /**
     * You can limit the length of string.
     * 
     * Also, multiple range conditions are also possible.
     */
    string: string & (
        | (tags.MinLength<3> & tags.MaxLength<24>)
        | (tags.MinLength<40> & tags.MaxLength<100>)
    );
 
    /**
     * You can limit the pattern of string.
     * 
     * @pattern ^[a-z]+$
     */
    pattern: string;
 
    /**
     * You can limit the format of string.
     * 
     * @format date-time
     */
    format: string | null;
    
    /**
     * In the Array case, possible to restrict its elements.
     */
    array: Array<string & tags.Format<"uuid">> & tags.MinItems<3>;
}

Restrictions

JSON schema does not support bigint type.

So if you use bigint type in one of your onetarget schemas, typia will make compile error like below.

json.application.ts
import typia, { tags } from "typia";
 
interface Something {
    bigint: bigint;
    array: bigint[];
    nested: Nested;
}
interface Nested {
    uint64: bigint & tags.Type<"uint64">;
}
 
typia.json.application<[Something], "ajv">();

Also, if you put any type of native classes like Map or Uint8Array, it would be considered as an empty object. By the way, only Date class is exceptional, and it would be considered as string & Format<"date-time"> type like below.

json.application.native.ts
import typia from "typia";
 
interface Native {
    date: Date;
    bytes: Uint8Array;
    map: Map<string, number>;
}
typia.json.application<[Native], "ajv">();