đź“– Guide Documents
Enhanced JSON
JSON Schema

application() function

export namespace json {
  export function application<
    Schemas extends unknown[],
    Version extends "3.0" | "3.1" = "3.1",
  >(): IJsonApplication<Version>;
}

JSON schema generator.

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

If you call the typia.json.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 "OpenAPI v3.0" and "OpenAPI v3.1" are a little bit different. Therefore, you have to consider which value to assign in the Version 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.json.application<[IMember], "3.0">();
 
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], "3.1">();
 
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>;
}

Customization

If what you want is not just filling regular properties of JSON schema specification, but to adding custom properties into the JSON schema definition, you can do it through the tags.TagBase.schema property type or tags.JsonSchemaPlugin type.

For reference, the custom property must be started with x- prefix. It's a rule of JSON schema.

examples/src/json-schema-custom.ts
import typia, { tags } from "typia";
 
type Monetary<Value extends string> = tags.TagBase<{
  target: "number";
  kind: "monetary";
  value: Value;
  schema: {
    "x-monetary": Value;
  };
}>;
 
type Placeholder<Value extends string> = tags.JsonSchemaPlugin<{
  "x-placeholder": Value;
}>;
 
interface IAccount {
  code: string & Placeholder<"Write you account code please">;
  balance: number & Monetary<"dollar">;
};
 
typia.json.application<[IAccount]>();

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]>();

Also, if you put any type of native classes like Map or Uint8Array, it would also be error, either. 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;
}
typia.json.application<[Native]>();