typia.json.schemas โ emit JSON Schema / OpenAPI from a TypeScript type
If youโve ever hand-written a JSON Schema or an OpenAPI components block, you know how mechanical it is. typia generates it from the TypeScript type at compile time. Same model as the validators โ no extra schema file to maintain.
namespace json {
function schema<T, Version extends "3.0" | "3.1" = "3.1">(): IJsonSchemaUnit<Version, T>;
function schemas<Schemas extends unknown[], Version extends "3.0" | "3.1" = "3.1">(): IJsonSchemaCollection<Version, Schemas>;
function application<Class extends object, Version extends "3.0" | "3.1" = "3.1">(): IJsonSchemaApplication<Version, Class>;
}| Function | Use case |
|---|---|
json.schema<T>() | A single top-level schema, plus a components map for any $refs the type pulls in |
json.schemas<[T1, T2, ...]>() | Multiple top-level types sharing one components map (the common case for an OpenAPI components.schemas) |
json.application<Class>() | Class methods โ a list of {name, parameters, output} JSON Schemas โ handy for framework-neutral tooling that wants per-method schemas without typiaโs LLM-specific config |
For the LLM-specific shape (with $defs, additionalProperties: false, strict mode, โฆ), use typia.llm.parameters or typia.llm.application instead.
Version selects the JSON Schema dialect:
"3.1"(default) โ OpenAPI 3.1, which is JSON Schema 2020-12. Supports tuples, pattern properties,nullas a primitive."3.0"โ OpenAPI 3.0 / Swagger compatibility. No tuples, no pattern properties.
Stick with "3.1" unless a downstream consumer demands the older dialect.
First example
import typia, { tags } from "typia";
interface User {
id: string & tags.Format<"uuid">;
age: number & tags.Type<"uint32">;
email?: string & tags.Format<"email">;
}
const schemas = typia.json.schemas<[User]>();
// โ an IJsonSchemaCollection with `User` under components.schemasThe output is a plain object โ drop it into your OpenAPI spec, hand it to ajv if you must, or save it to disk for tooling that wants schemas at rest.
TypeScript Source
import typia, { tags } from "typia";
export const MemberSchema = typia.json.schemas<[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>;
}Compiled JavaScript
/* @ttsc-rewritten */
export const MemberSchema = {
components: {
schemas: {
IMember: {
type: "object",
properties: {
age: {
type: "integer",
minimum: 0,
exclusiveMinimum: 19,
maximum: 100,
description:
"Age of the member.\n\nFor reference, only adult can be a member.",
},
email: {
type: "string",
format: "email",
description: "Email address of the member.",
},
id: {
type: "string",
format: "uuid",
description: "Unique user ID generated by server.",
},
},
required: ["id", "email", "age"],
additionalProperties: false,
},
},
},
schemas: [
{
$ref: "#/components/schemas/IMember",
},
],
version: "3.0",
};undefined
export namespace json {
export function schemas<
Schemas extends unknown[],
Version extends "3.0" | "3.1" = "3.1",
>(): IJsonSchemaCollection<Version>;
}undefined
import { OpenApi } from "../openapi/OpenApi";
import { OpenApiV3 } from "../openapi/OpenApiV3";
/**
* Collection of JSON schemas generated from multiple TypeScript types.
*
* `IJsonSchemaCollection` holds JSON schemas for multiple TypeScript types
* generated at compile time by `typia.json.schemas<[T1, T2, ...]>()`. The
* schemas share a common components pool to avoid duplication when types
* reference each other.
*
* This is useful when you need schemas for multiple related types and want to
* share component definitions between them. For single types, use
* {@link IJsonSchemaUnit} instead. For function schemas, see
* {@link IJsonSchemaApplication}.
*
* The collection contains:
*
* - {@link IV3_1.schemas | schemas}: Array of schemas, one per input type
* - {@link IV3_1.components | components}: Shared `$ref` definitions
* - {@link IV3_1.__types | __types}: Phantom property for type inference
*
* @author Jeongho Nam - https://github.com/samchon
* @template Version OpenAPI version ("3.0" or "3.1")
* @template Types Tuple of original TypeScript types
*/
export type IJsonSchemaCollection<
Version extends "3.0" | "3.1" = "3.1",
Types = unknown[],
> = Version extends "3.0"
? IJsonSchemaCollection.IV3_0<Types>
: IJsonSchemaCollection.IV3_1<Types>;
export namespace IJsonSchemaCollection {
/**
* JSON Schema collection for OpenAPI v3.0 specification.
*
* Uses OpenAPI v3.0 compatible JSON Schema format. In v3.0, nullable types
* are expressed with `nullable: true` rather than v3.1's `type` arrays.
*
* @template Types Tuple of original TypeScript types for phantom type
* preservation
*/
export interface IV3_0<Types = unknown[]> {
/**
* OpenAPI specification version.
*
* Always `"3.0"` for this variant. Use this discriminator to determine
* which schema format is in use.
*/
version: "3.0";
/**
* Generated JSON schemas, one per input type.
*
* Array of schemas in the same order as the input type tuple. Each schema
* may reference definitions in {@link components}.
*/
schemas: OpenApiV3.IJsonSchema[];
/**
* Shared schema definitions for `$ref` references.
*
* Contains named schemas used across multiple types in the collection.
* Reduces duplication when types share common structures.
*/
components: OpenApiV3.IComponents;
/**
* Phantom property for TypeScript generic type preservation.
*
* This property exists only in the type system to preserve the `Types`
* generic parameter. It is always `undefined` at runtime and should not be
* accessed or used in application code.
*/
__types?: Types | undefined;
}
/**
* JSON Schema collection for OpenAPI v3.1 specification.
*
* Uses OpenAPI v3.1 compatible JSON Schema format. v3.1 aligns more closely
* with JSON Schema draft 2020-12, supporting features like `type` arrays for
* nullable types and `const` values.
*
* @template Types Tuple of original TypeScript types for phantom type
* preservation
*/
export interface IV3_1<Types = unknown[]> {
/**
* OpenAPI specification version.
*
* Always `"3.1"` for this variant. Use this discriminator to determine
* which schema format is in use.
*/
version: "3.1";
/**
* Shared schema definitions for `$ref` references.
*
* Contains named schemas used across multiple types in the collection.
* Reduces duplication when types share common structures.
*/
components: OpenApi.IComponents;
/**
* Generated JSON schemas, one per input type.
*
* Array of schemas in the same order as the input type tuple. Each schema
* may reference definitions in {@link components}.
*/
schemas: OpenApi.IJsonSchema[];
/**
* Phantom property for TypeScript generic type preservation.
*
* This property exists only in the type system to preserve the `Types`
* generic parameter. It is always `undefined` at runtime and should not be
* accessed or used in application code.
*/
__types?: Types | undefined;
}
}undefined
import { IJsonSchemaAttribute } from "../schema/IJsonSchemaAttribute";
import * as tags from "../tags";
/**
* Emended OpenAPI v3.2 specification.
*
* `OpenApi` is a refined OpenAPI v3.2 specification that normalizes ambiguous
* and redundant expressions from various OpenAPI versions (Swagger 2.0, OpenAPI
* 3.0, 3.1, 3.2). This unified format simplifies schema processing for `typia`
* and `@nestia/sdk`.
*
* Key simplifications:
*
* - Schema `$ref` references are unified to `#/components/schemas/{name}` format
* - Non-schema references (parameters, responses) are resolved inline
* - `nullable` is converted to `{ oneOf: [schema, { type: "null\" }] }`
* - `allOf` compositions are merged into single schemas
* - Schema attributes are normalized across all versions
*
* Use `HttpLlm.application()` from `@typia/utils` to convert
* `OpenApi.IDocument` into {@link IHttpLlmApplication} for LLM function
* calling.
*
* @author Jeongho Nam - https://github.com/samchon
*/
export namespace OpenApi {
/**
* HTTP method supported by OpenAPI operations.
*
* Standard HTTP methods used in REST APIs. Each path can have multiple
* operations, one per HTTP method.
*/
export type Method =
| "get"
| "post"
| "put"
| "delete"
| "options"
| "head"
| "patch"
| "trace"
| "query";
/**
* Root document structure for emended OpenAPI v3.2.
*
* Contains all API metadata, paths, operations, and reusable components. The
* `x-samchon-emended-v4` marker indicates this document has been processed by
* `samchon/typia` to normalize schema formats.
*/
export interface IDocument {
/** OpenAPI version. */
openapi: `3.2.${number}`;
/** List of servers providing the API. */
servers?: IServer[];
/** API metadata. */
info?: IDocument.IInfo;
/** Reusable components (schemas, security schemes). */
components: IComponents;
/** Available API paths and operations. */
paths?: Record<string, IPath>;
/** Webhook definitions. */
webhooks?: Record<string, IPath>;
/** Global security requirements. */
security?: Record<string, string[]>[];
/** Tag definitions for grouping operations. */
tags?: IDocument.ITag[];
/** Marker for emended document by `typia` */
"x-typia-emended-v12": true;
}
export namespace IDocument {
/**
* API metadata and identification.
*
* Contains essential information about the API including title, version,
* contact information, and licensing details.
*/
export interface IInfo {
/** API title. */
title: string;
/** Short summary. */
summary?: string;
/** Full description. */
description?: string;
/** Terms of service URL. */
termsOfService?: string;
/** Contact information. */
contact?: IContact;
/** License information. */
license?: ILicense;
/** API version. */
version: string;
}
/** Tag for grouping operations. */
export interface ITag {
/** Tag name. */
name: string;
/** Short summary for display in tag lists. */
summary?: string;
/** Tag description. */
description?: string;
/** Parent tag name for hierarchical organization. */
parent?: string;
/** Tag classification (e.g., "nav", "badge"). */
kind?: string;
}
/** Contact information. */
export interface IContact {
/** Contact name. */
name?: string;
/** Contact URL. */
url?: string;
/** Contact email. */
email?: string & tags.Format<"email">;
}
/** License information. */
export interface ILicense {
/** License name. */
name: string;
/** SPDX license identifier. */
identifier?: string;
/** License URL. */
url?: string;
}
}
/** Server providing the API. */
export interface IServer {
/** Server URL. */
url: string;
/** Server description. */
description?: string;
/** URL template variables. */
variables?: Record<string, IServer.IVariable>;
}
export namespace IServer {
/** URL template variable. */
export interface IVariable {
/** Default value. */
default: string;
/** Allowed values. */
enum?: string[];
/** Variable description. */
description?: string;
}
}
/** Path item containing operations by HTTP method. */
export interface IPath extends Partial<Record<Method, IOperation>> {
/** Path-level servers. */
servers?: IServer[];
/** Path summary. */
summary?: string;
/** Path description. */
description?: string;
/**
* Additional non-standard HTTP method operations (e.g., LINK, UNLINK,
* PURGE).
*/
additionalOperations?: Record<string, IOperation>;
}
/** API operation metadata. */
export interface IOperation {
/** Unique operation identifier. */
operationId?: string;
/** Operation parameters. */
parameters?: IOperation.IParameter[];
/** Request body. */
requestBody?: IOperation.IRequestBody;
/** Response definitions by status code. */
responses?: Record<string, IOperation.IResponse>;
/** Operation-level servers. */
servers?: IServer[];
/** Short summary. */
summary?: string;
/** Full description. */
description?: string;
/** Security requirements. */
security?: Record<string, string[]>[];
/** Operation tags for grouping. */
tags?: string[];
/** Whether deprecated. */
deprecated?: boolean;
/** Excludes from LLM function calling when `true`. */
"x-samchon-human"?: boolean;
/** Custom accessor path for migration. */
"x-samchon-accessor"?: string[];
/** Controller name for code generation. */
"x-samchon-controller"?: string;
}
export namespace IOperation {
/** Operation parameter. */
export interface IParameter {
/** Parameter name. */
name?: string;
/** Parameter location. */
in: "path" | "query" | "querystring" | "header" | "cookie";
/** Parameter schema. */
schema: IJsonSchema;
/** Whether required. */
required?: boolean;
/** Parameter description. */
description?: string;
/** Example value. */
example?: any;
/** Named examples. */
examples?: Record<string, IExample>;
}
/** Request body. */
export interface IRequestBody {
/** Body content by media type. */
content?: IContent;
/** Body description. */
description?: string;
/** Whether required. */
required?: boolean;
/** Nestia encryption flag. */
"x-nestia-encrypted"?: boolean;
}
/** Response definition. */
export interface IResponse {
/** Response headers. */
headers?: Record<string, IOperation.IParameter>;
/** Response content by media type. */
content?: IContent;
/** Response description. */
description?: string;
/** Nestia encryption flag. */
"x-nestia-encrypted"?: boolean;
}
/** Content by media type. */
export interface IContent extends Partial<
Record<ContentType, IMediaType>
> {}
/** Media type definition. */
export interface IMediaType {
/** Content schema. */
schema?: IJsonSchema;
/** Schema for streaming items (SSE, JSON Lines, etc.). */
itemSchema?: IJsonSchema;
/** Example value. */
example?: any;
/** Named examples. */
examples?: Record<string, IExample>;
}
/** Supported content types. */
export type ContentType =
| "text/plain"
| "application/json"
| "application/x-www-form-url-encoded"
| "multipart/form-data"
| "*/*"
| (string & {});
}
/** Example value definition. */
export interface IExample {
/** Example summary. */
summary?: string;
/** Example description. */
description?: string;
/** Example value. */
value?: any;
/** External value URL. */
externalValue?: string;
}
/** Reusable components storage. */
export interface IComponents {
/** Named schemas. */
schemas?: Record<string, IJsonSchema>;
/** Named security schemes. */
securitySchemes?: Record<string, ISecurityScheme>;
}
/**
* JSON Schema type for emended OpenAPI v3.1.
*
* Represents all possible JSON Schema types in the normalized OpenAPI format.
* This is a discriminated union - check the `type` property or use type
* guards to narrow to specific schema types.
*
* Unlike raw JSON Schema, this format:
*
* - Uses `oneOf` instead of `anyOf` for union types
* - Separates `IArray` (homogeneous) from `ITuple` (heterogeneous)
* - Normalizes nullable types to `oneOf` with null schema
*/
export type IJsonSchema =
| IJsonSchema.IConstant
| IJsonSchema.IBoolean
| IJsonSchema.IInteger
| IJsonSchema.INumber
| IJsonSchema.IString
| IJsonSchema.IArray
| IJsonSchema.ITuple
| IJsonSchema.IObject
| IJsonSchema.IReference
| IJsonSchema.IOneOf
| IJsonSchema.INull
| IJsonSchema.IUnknown;
export namespace IJsonSchema {
/** Constant value type. */
export interface IConstant extends IJsonSchemaAttribute {
/** Constant value. */
const: boolean | number | string;
}
/** Boolean type. */
export interface IBoolean extends IJsonSchemaAttribute.IBoolean {
/** Default value. */
default?: boolean;
}
/** Integer type. */
export interface IInteger extends IJsonSchemaAttribute.IInteger {
/** Default value. */
default?: number & tags.Type<"int64">;
/** Minimum value. */
minimum?: number & tags.Type<"int64">;
/** Maximum value. */
maximum?: number & tags.Type<"int64">;
/** Exclusive minimum. */
exclusiveMinimum?: number & tags.Type<"int64">;
/** Exclusive maximum. */
exclusiveMaximum?: number & tags.Type<"int64">;
/** Multiple of constraint. */
multipleOf?: number & tags.ExclusiveMinimum<0>;
}
/** Number (double) type. */
export interface INumber extends IJsonSchemaAttribute.INumber {
/** Default value. */
default?: number;
/** Minimum value. */
minimum?: number;
/** Maximum value. */
maximum?: number;
/** Exclusive minimum. */
exclusiveMinimum?: number;
/** Exclusive maximum. */
exclusiveMaximum?: number;
/** Multiple of constraint. */
multipleOf?: number & tags.ExclusiveMinimum<0>;
}
/** String type. */
export interface IString extends IJsonSchemaAttribute.IString {
/** Default value. */
default?: string;
/** String format. */
format?:
| "binary"
| "byte"
| "password"
| "regex"
| "uuid"
| "email"
| "hostname"
| "idn-email"
| "idn-hostname"
| "iri"
| "iri-reference"
| "ipv4"
| "ipv6"
| "uri"
| "uri-reference"
| "uri-template"
| "url"
| "date-time"
| "date"
| "time"
| "duration"
| "json-pointer"
| "relative-json-pointer"
| (string & {});
/** Regex pattern. */
pattern?: string;
/** Content media type. */
contentMediaType?: string;
/** Minimum length. */
minLength?: number & tags.Type<"uint64">;
/** Maximum length. */
maxLength?: number & tags.Type<"uint64">;
}
/** Array type. */
export interface IArray extends IJsonSchemaAttribute.IArray {
/** Element type. */
items: IJsonSchema;
/** Whether elements must be unique. */
uniqueItems?: boolean;
/** Minimum items. */
minItems?: number & tags.Type<"uint64">;
/** Maximum items. */
maxItems?: number & tags.Type<"uint64">;
}
/** Tuple type. */
export interface ITuple extends IJsonSchemaAttribute {
/** Type discriminator. */
type: "array";
/** Tuple element types. */
prefixItems: IJsonSchema[];
/** Rest element type or `true` for any. */
additionalItems?: boolean | IJsonSchema;
/** Whether elements must be unique. */
uniqueItems?: boolean;
/** Minimum items. */
minItems?: number & tags.Type<"uint64">;
/** Maximum items. */
maxItems?: number & tags.Type<"uint64">;
}
/** Object type. */
export interface IObject extends IJsonSchemaAttribute.IObject {
/** Property schemas. */
properties?: Record<string, IJsonSchema>;
/** Additional properties schema or `true` for any. */
additionalProperties?: boolean | IJsonSchema;
/** Required property names. */
required?: string[];
}
/** Reference to named schema. */
export interface IReference<Key = string> extends IJsonSchemaAttribute {
/** Reference path (e.g., `#/components/schemas/TypeName`). */
$ref: Key;
}
/** Union type (`oneOf`). */
export interface IOneOf extends IJsonSchemaAttribute {
/** Union member schemas. */
oneOf: Exclude<IJsonSchema, IJsonSchema.IOneOf>[];
/** Discriminator for tagged unions. */
discriminator?: IOneOf.IDiscriminator;
}
export namespace IOneOf {
/** Discriminator for tagged unions. */
export interface IDiscriminator {
/** Discriminator property name. */
propertyName: string;
/** Value to schema mapping. */
mapping?: Record<string, string>;
}
}
/** Null type. */
export interface INull extends IJsonSchemaAttribute.INull {
/** Default value. */
default?: null;
}
/** Unknown (`any`) type. */
export interface IUnknown extends IJsonSchemaAttribute.IUnknown {
/** Default value. */
default?: any;
}
}
/** Security scheme types. */
export type ISecurityScheme =
| ISecurityScheme.IApiKey
| ISecurityScheme.IHttpBasic
| ISecurityScheme.IHttpBearer
| ISecurityScheme.IOAuth2
| ISecurityScheme.IOpenId;
export namespace ISecurityScheme {
/** API key authentication. */
export interface IApiKey {
/** Scheme type. */
type: "apiKey";
/** Key location. */
in?: "header" | "query" | "cookie";
/** Key name. */
name?: string;
/** Scheme description. */
description?: string;
}
/** HTTP basic authentication. */
export interface IHttpBasic {
/** Scheme type. */
type: "http";
/** Authentication scheme. */
scheme: "basic";
/** Scheme description. */
description?: string;
}
/** HTTP bearer authentication. */
export interface IHttpBearer {
/** Scheme type. */
type: "http";
/** Authentication scheme. */
scheme: "bearer";
/** Bearer token format hint. */
bearerFormat?: string;
/** Scheme description. */
description?: string;
}
/** OAuth2 authentication. */
export interface IOAuth2 {
/** Scheme type. */
type: "oauth2";
/** OAuth2 flows. */
flows: IOAuth2.IFlowSet;
/** OAuth2 metadata discovery URL. */
oauth2MetadataUrl?: string;
/** Scheme description. */
description?: string;
}
/** OpenID Connect authentication. */
export interface IOpenId {
/** Scheme type. */
type: "openIdConnect";
/** OpenID Connect discovery URL. */
openIdConnectUrl: string;
/** Scheme description. */
description?: string;
}
export namespace IOAuth2 {
/** OAuth2 flow configurations. */
export interface IFlowSet {
/** Authorization code flow. */
authorizationCode?: IFlow;
/** Implicit flow. */
implicit?: Omit<IFlow, "tokenUrl">;
/** Password flow. */
password?: Omit<IFlow, "authorizationUrl">;
/** Client credentials flow. */
clientCredentials?: Omit<IFlow, "authorizationUrl">;
/** Device authorization flow. */
deviceAuthorization?: IDeviceFlow;
}
/** OAuth2 flow configuration. */
export interface IFlow {
/** Authorization URL. */
authorizationUrl?: string;
/** Token URL. */
tokenUrl?: string;
/** Refresh URL. */
refreshUrl?: string;
/** Available scopes. */
scopes?: Record<string, string>;
}
/** OAuth2 device authorization flow. */
export interface IDeviceFlow {
/** Device authorization URL. */
deviceAuthorizationUrl: string;
/** Token URL. */
tokenUrl: string;
/** Refresh URL. */
refreshUrl?: string;
/** Available scopes. */
scopes?: Record<string, string>;
}
}
}
}undefined
import { IJsonSchemaAttribute } from "../schema/IJsonSchemaAttribute";
import * as tags from "../tags";
/**
* OpenAPI v3.0 specification types.
*
* `OpenApiV3` contains TypeScript type definitions for OpenAPI v3.0 documents.
* Used for parsing and generating OpenAPI v3.0 specifications. For a normalized
* format that unifies all OpenAPI versions, use {@link OpenApi} instead.
*
* Key differences from v3.1:
*
* - Uses `nullable: true` instead of `type: ["string", "null"]`
* - No `const` keyword support
* - No `prefixItems` for tuples
*
* @author Jeongho Nam - https://github.com/samchon
*/
export namespace OpenApiV3 {
/** HTTP method of the operation. */
export type Method =
| "get"
| "post"
| "put"
| "delete"
| "options"
| "head"
| "patch"
| "trace";
/* -----------------------------------------------------------
DOCUMENTS
----------------------------------------------------------- */
/** OpenAPI document structure. */
export interface IDocument {
/** OpenAPI version. */
openapi: "3.0" | `3.0.${number}`;
/** List of servers. */
servers?: IServer[];
/** API metadata. */
info?: IDocument.IInfo;
/** Reusable components. */
components?: IComponents;
/** API paths and operations. */
paths?: Record<string, IPath>;
/** Global security requirements. */
security?: Record<string, string[]>[];
/** Tag definitions. */
tags?: IDocument.ITag[];
}
export namespace IDocument {
/** API metadata. */
export interface IInfo {
/** API title. */
title: string;
/** API description. */
description?: string;
/** Terms of service URL. */
termsOfService?: string;
/** Contact information. */
contact?: IContact;
/** License information. */
license?: ILicense;
/** API version. */
version: string;
}
/** Tag for grouping operations. */
export interface ITag {
/** Tag name. */
name: string;
/** Tag description. */
description?: string;
}
/** Contact information. */
export interface IContact {
/** Contact name. */
name?: string;
/** Contact URL. */
url?: string;
/** Contact email. */
email?: string & tags.Format<"email">;
}
/** License information. */
export interface ILicense {
/** License name. */
name: string;
/** License URL. */
url?: string;
}
}
/** Server providing the API. */
export interface IServer {
/** Server URL. */
url: string;
/** Server description. */
description?: string;
/** URL template variables. */
variables?: Record<string, IServer.IVariable>;
}
export namespace IServer {
/** URL template variable. */
export interface IVariable {
/** Default value. */
default: string;
/** Allowed values. */
enum?: string[];
/** Variable description. */
description?: string;
}
}
/* -----------------------------------------------------------
PATH ITEMS
----------------------------------------------------------- */
/** Path item containing operations by HTTP method. */
export interface IPath extends Partial<
Record<Method, IOperation | undefined>
> {
/** Path-level parameters. */
parameters?: Array<
| IOperation.IParameter
| IJsonSchema.IReference<`#/components/headers/${string}`>
| IJsonSchema.IReference<`#/components/parameters/${string}`>
>;
/** Path-level servers. */
servers?: IServer[];
/** Path summary. */
summary?: string;
/** Path description. */
description?: string;
/**
* Non-standard HTTP method operations (extension).
*
* Used when downgrading from OpenAPI v3.2 to preserve non-standard methods
* like `query` or custom methods.
*/
"x-additionalOperations"?: Record<string, IOperation>;
}
/** API operation metadata. */
export interface IOperation {
/** Unique operation identifier. */
operationId?: string;
/** Operation parameters. */
parameters?: Array<
| IOperation.IParameter
| IJsonSchema.IReference<`#/components/headers/${string}`>
| IJsonSchema.IReference<`#/components/parameters/${string}`>
>;
/** Request body. */
requestBody?:
| IOperation.IRequestBody
| IJsonSchema.IReference<`#/components/requestBodies/${string}`>;
/** Response definitions by status code. */
responses?: Record<
string,
| IOperation.IResponse
| IJsonSchema.IReference<`#/components/responses/${string}`>
>;
/** Operation-level servers. */
servers?: IServer[];
/** Short summary. */
summary?: string;
/** Full description. */
description?: string;
/** Security requirements. */
security?: Record<string, string[]>[];
/** Operation tags. */
tags?: string[];
/** Whether deprecated. */
deprecated?: boolean;
}
export namespace IOperation {
/** Operation parameter. */
export interface IParameter {
/** Parameter name. */
name?: string;
/** Parameter location. */
in: "path" | "query" | "header" | "cookie";
/** Parameter schema. */
schema: IJsonSchema;
/** Whether required. */
required?: boolean;
/** Parameter description. */
description?: string;
/** Example value. */
example?: any;
/** Named examples. */
examples?: Record<
string,
IExample | IJsonSchema.IReference<`#/components/examples/${string}`>
>;
}
/** Request body. */
export interface IRequestBody {
/** Body description. */
description?: string;
/** Whether required. */
required?: boolean;
/** Body content by media type. */
content?: Record<string, IMediaType>;
}
/** Response definition. */
export interface IResponse {
/** Response content by media type. */
content?: Record<string, IMediaType>;
/** Response headers. */
headers?: Record<
string,
| Omit<IOperation.IParameter, "in">
| IJsonSchema.IReference<`#/components/headers/${string}`>
>;
/** Response description. */
description?: string;
}
/** Media type definition. */
export interface IMediaType {
/** Content schema. */
schema?: IJsonSchema;
/** Example value. */
example?: any;
/** Named examples. */
examples?: Record<
string,
IExample | IJsonSchema.IReference<`#/components/examples/${string}`>
>;
}
}
/** Example value definition. */
export interface IExample {
/** Example summary. */
summary?: string;
/** Example description. */
description?: string;
/** Example value. */
value?: any;
/** External value URL. */
externalValue?: string;
}
/* -----------------------------------------------------------
SCHEMA DEFINITIONS
----------------------------------------------------------- */
/** Reusable components storage. */
export interface IComponents {
/** Named schemas. */
schemas?: Record<string, IJsonSchema>;
/** Named responses. */
responses?: Record<string, IOperation.IResponse>;
/** Named parameters. */
parameters?: Record<string, IOperation.IParameter>;
/** Named request bodies. */
requestBodies?: Record<string, IOperation.IRequestBody>;
/** Named security schemes. */
securitySchemes?: Record<string, ISecurityScheme>;
/** Named headers. */
headers?: Record<string, Omit<IOperation.IParameter, "in">>;
/** Named examples. */
examples?: Record<string, IExample>;
}
/** JSON Schema type for OpenAPI v3.0. */
export type IJsonSchema =
| IJsonSchema.IBoolean
| IJsonSchema.IInteger
| IJsonSchema.INumber
| IJsonSchema.IString
| IJsonSchema.IArray
| IJsonSchema.IObject
| IJsonSchema.IReference
| IJsonSchema.IAllOf
| IJsonSchema.IAnyOf
| IJsonSchema.IOneOf
| IJsonSchema.INullOnly
| IJsonSchema.IUnknown;
export namespace IJsonSchema {
/** Boolean type. */
export interface IBoolean
extends Omit<IJsonSchemaAttribute.IBoolean, "examples">, __IAttribute {
/** Whether nullable. */
nullable?: boolean;
/** Default value. */
default?: boolean | null;
/** Allowed values. */
enum?: Array<boolean | null>;
}
/** Integer type. */
export interface IInteger
extends Omit<IJsonSchemaAttribute.IInteger, "examples">, __IAttribute {
/** Whether nullable. */
nullable?: boolean;
/** Default value. */
default?: (number & tags.Type<"int64">) | null;
/** Allowed values. */
enum?: Array<(number & tags.Type<"int64">) | null>;
/** Minimum value. */
minimum?: number & tags.Type<"int64">;
/** Maximum value. */
maximum?: number & tags.Type<"int64">;
/** Exclusive minimum. */
exclusiveMinimum?: number | boolean;
/** Exclusive maximum. */
exclusiveMaximum?: number | boolean;
/** Multiple of constraint. */
multipleOf?: number & tags.ExclusiveMinimum<0>;
}
/** Number (double) type. */
export interface INumber
extends Omit<IJsonSchemaAttribute.INumber, "examples">, __IAttribute {
/** Whether nullable. */
nullable?: boolean;
/** Default value. */
default?: number | null;
/** Allowed values. */
enum?: Array<number | null>;
/** Minimum value. */
minimum?: number;
/** Maximum value. */
maximum?: number;
/** Exclusive minimum. */
exclusiveMinimum?: number | boolean;
/** Exclusive maximum. */
exclusiveMaximum?: number | boolean;
/** Multiple of constraint. */
multipleOf?: number & tags.ExclusiveMinimum<0>;
}
/** String type. */
export interface IString
extends Omit<IJsonSchemaAttribute.IString, "examples">, __IAttribute {
/** Whether nullable. */
nullable?: boolean;
/** Default value. */
default?: string | null;
/** Allowed values. */
enum?: Array<string | null>;
/** String format. */
format?:
| "binary"
| "byte"
| "password"
| "regex"
| "uuid"
| "email"
| "hostname"
| "idn-email"
| "idn-hostname"
| "iri"
| "iri-reference"
| "ipv4"
| "ipv6"
| "uri"
| "uri-reference"
| "uri-template"
| "url"
| "date-time"
| "date"
| "time"
| "duration"
| "json-pointer"
| "relative-json-pointer"
| (string & {});
/** Regex pattern. */
pattern?: string;
/** Minimum length. */
minLength?: number & tags.Type<"uint64">;
/** Maximum length. */
maxLength?: number & tags.Type<"uint64">;
}
/** Array type. */
export interface IArray
extends Omit<IJsonSchemaAttribute.IArray, "examples">, __IAttribute {
/** Whether nullable. */
nullable?: boolean;
/** Element type. */
items: IJsonSchema;
/** Whether elements must be unique. */
uniqueItems?: boolean;
/** Minimum items. */
minItems?: number & tags.Type<"uint64">;
/** Maximum items. */
maxItems?: number & tags.Type<"uint64">;
}
/** Object type. */
export interface IObject
extends Omit<IJsonSchemaAttribute.IObject, "examples">, __IAttribute {
/** Whether nullable. */
nullable?: boolean;
/** Property schemas. */
properties?: Record<string, IJsonSchema>;
/** Required property names. */
required?: string[];
/** Additional properties schema. */
additionalProperties?: boolean | IJsonSchema;
/** Maximum properties. */
maxProperties?: number;
/** Minimum properties. */
minProperties?: number;
}
/** Reference to a named schema. */
export interface IReference<Key = string> extends __IAttribute {
/** Reference path. */
$ref: Key;
}
/** All-of combination. */
export interface IAllOf extends __IAttribute {
/** Schemas to combine. */
allOf: IJsonSchema[];
}
/** Any-of union. */
export interface IAnyOf extends __IAttribute {
/** Union member schemas. */
anyOf: IJsonSchema[];
}
/** One-of union. */
export interface IOneOf extends __IAttribute {
/** Union member schemas. */
oneOf: IJsonSchema[];
/** Discriminator for tagged unions. */
discriminator?: IOneOf.IDiscriminator;
}
export namespace IOneOf {
/** Discriminator for tagged unions. */
export interface IDiscriminator {
/** Discriminator property name. */
propertyName: string;
/** Value to schema mapping. */
mapping?: Record<string, string>;
}
}
/** Null type. */
export interface INullOnly
extends Omit<IJsonSchemaAttribute.INull, "examples">, __IAttribute {
/** Default value. */
default?: null;
}
/** Unknown type. */
export interface IUnknown
extends Omit<IJsonSchemaAttribute.IUnknown, "examples">, __IAttribute {
/** Default value. */
default?: any;
}
/** @ignore Base Attribute interface. */
export interface __IAttribute extends Omit<
IJsonSchemaAttribute,
"examples"
> {
/** Example values. */
examples?: any[] | Record<string, any>;
}
}
/** Security scheme types. */
export type ISecurityScheme =
| ISecurityScheme.IApiKey
| ISecurityScheme.IHttpBasic
| ISecurityScheme.IHttpBearer
| ISecurityScheme.IOAuth2
| ISecurityScheme.IOpenId;
export namespace ISecurityScheme {
/** API key authentication. */
export interface IApiKey {
/** Scheme type. */
type: "apiKey";
/** Key location. */
in?: "header" | "query" | "cookie";
/** Key name. */
name?: string;
/** Scheme description. */
description?: string;
}
/** HTTP basic authentication. */
export interface IHttpBasic {
/** Scheme type. */
type: "http";
/** Authentication scheme. */
scheme: "basic";
/** Scheme description. */
description?: string;
}
/** HTTP bearer authentication. */
export interface IHttpBearer {
/** Scheme type. */
type: "http";
/** Authentication scheme. */
scheme: "bearer";
/** Bearer token format hint. */
bearerFormat?: string;
/** Scheme description. */
description?: string;
}
/** OAuth2 authentication. */
export interface IOAuth2 {
/** Scheme type. */
type: "oauth2";
/** OAuth2 flows. */
flows: IOAuth2.IFlowSet;
/** Scheme description. */
description?: string;
}
/** OpenID Connect authentication. */
export interface IOpenId {
/** Scheme type. */
type: "openIdConnect";
/** OpenID Connect discovery URL. */
openIdConnectUrl: string;
/** Scheme description. */
description?: string;
}
export namespace IOAuth2 {
/** OAuth2 flow configurations. */
export interface IFlowSet {
/** Authorization code flow. */
authorizationCode?: IFlow;
/** Implicit flow. */
implicit?: Omit<IFlow, "tokenUrl">;
/** Password flow. */
password?: Omit<IFlow, "authorizationUrl">;
/** Client credentials flow. */
clientCredentials?: Omit<IFlow, "authorizationUrl">;
}
/** OAuth2 flow configuration. */
export interface IFlow {
/** Authorization URL. */
authorizationUrl?: string;
/** Token URL. */
tokenUrl?: string;
/** Refresh URL. */
refreshUrl?: string;
/** Available scopes. */
scopes?: Record<string, string>;
}
}
}
}What gets included
Anything you express in the TypeScript type carries over:
tags.Format<"uuid">โ"format": "uuid"tags.MaxLength<100>โ"maxLength": 100tags.Minimum<0>โ"minimum": 0- JSDoc description on a property โ
"description": "..."
A few JSON-Schema-only comment tags are also recognized โ they donโt affect runtime validation but they show up in the emitted schema:
| Tag | Effect |
|---|---|
@title Something | Sets title |
@deprecated | Sets deprecated: true |
@hidden / @internal | Excludes the field from the emitted schema |
TypeScript Source
import typia, { tags } from "typia";
export const SpecialCommentTagSchema = typia.json.schemas<[Special], "3.1">();
interface Special {
/**
* Deprecated tags are just used for marking.
*
* @deprecated
* @title Unsigned integer
*/
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>()`.
*
* @ignore
*/
hidden: boolean;
/**
* You can limit the range of number.
*
* @exclusiveMinimum 19
* @maximum 100
*/
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>;
}Compiled JavaScript
/* @ttsc-rewritten */
export const SpecialCommentTagSchema = {
components: {
schemas: {
Special: {
type: "object",
properties: {
type: {
type: "integer",
title: "Unsigned integer",
description: "Deprecated tags are just used for marking.",
deprecated: true,
},
pattern: {
type: "string",
pattern: "^[a-z]+$",
description: "You can limit the pattern of string.",
},
format: {
oneOf: [
{
type: "null",
},
{
type: "string",
format: "date-time",
},
],
description: "You can limit the format of string.",
},
array: {
type: "array",
minItems: 3,
items: {
type: "string",
format: "uuid",
},
description:
"In the Array case, possible to restrict its elements.",
},
number: {
type: "number",
exclusiveMinimum: 19,
maximum: 100,
description: "You can limit the range of number.",
},
string: {
oneOf: [
{
type: "string",
minLength: 3,
maxLength: 24,
},
{
type: "string",
minLength: 40,
maxLength: 100,
},
],
description:
"You can limit the length of string.\n\nAlso, multiple range conditions are also possible.",
},
},
required: ["type", "string", "pattern", "format", "array"],
additionalProperties: false,
},
},
},
schemas: [
{
$ref: "#/components/schemas/Special",
},
],
version: "3.1",
};Custom fields
JSON Schema reserves the x- prefix for non-standard extensions. To embed x-โฆ properties (for vendor-specific tooling, internal flags, anything that isnโt part of the standard), use tags.TagBase.schema or the tags.JsonSchemaPlugin helper:
TypeScript Source
import typia, { tags } from "typia";
export const SpecialTypeTagSchema = typia.json.schemas<[IAccount]>();
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 your account code please">;
balance: number & Monetary<"dollar">;
}Compiled JavaScript
/* @ttsc-rewritten */
export const SpecialTypeTagSchema = {
components: {
schemas: {
IAccount: {
type: "object",
properties: {
balance: {
type: "number",
"x-monetary": "dollar",
},
code: {
type: "string",
"x-placeholder": "Write your account code please",
},
},
required: ["code", "balance"],
additionalProperties: false,
},
},
},
schemas: [
{
$ref: "#/components/schemas/IAccount",
},
],
version: "3.1",
};Restrictions
bigint is rejected
JSON Schema has no bigint. typia refuses to compile a schema for a type that contains one:
TypeScript Source
import typia, { tags } from "typia";
interface Something {
bigint: bigint;
array: bigint[];
nested: Nested;
}
interface Nested {
uint64: bigint & tags.Type<"uint64">;
}
typia.json.schemas<[Something]>();Console Output
main.ts:12:1 - error TS(typia.json.schemas): unsupported type detected
- Something.bigint: bigint
- JSON does not support bigint type.
- Something.array: bigint
- JSON does not support bigint type.
- Nested.uint64: (bigint & Type<"uint64">)
- JSON does not support bigint type.Native classes โ only Date is allowed
Map, Set, Uint8Array, โฆ are rejected. Date is special-cased: it serializes as string & tags.Format<"date-time">, so typia accepts it.
TypeScript Source
import typia from "typia";
interface Native {
date: Date;
}
typia.json.schemas<[Native]>();Output JSON Schema
({
version: "3.1",
components: {
schemas: {
Native: {
type: "object",
properties: {
date: {
type: "string",
format: "date-time",
},
},
required: ["date"],
},
},
},
schemas: [
{
$ref: "#/components/schemas/Native",
},
],
});Where to go next
- Reading JSON safely โ
json.*Parse - Writing JSON fast โ
json.*Stringify - LLM-compatible schema for function calling โ
llm.parameters - Constraint cheatsheet โ Special Tags