stringify()
functions
undefined
export namespace json {
export function stringify<T>(input: T): string;
export function isStringify<T>(input: T | unknown): string | null;
export function assertStringify<T>(input: T | unknown): string;
export function validateStringify<T>(input: T | unknown): IValidation<string>;
}
undefined
/**
* Custom error class thrown when runtime assertion fails in `typia.assert<T>()` function.
*
* This error is thrown by the `typia.assert<T>()` function when the input value
* doesn't match the expected type.
*
* The error provides detailed information about the first assertion failure encountered,
* including the access path where the error occurred, the expected type, and the actual value.
*
* @template T - The expected type (generic for type safety)
* @author Jeongho Nam - https://github.com/samchon
* @example
* ```typescript
* interface IMember {
* name: string;
* age: number & ExclusiveMinimum<19>;
* }
*
* try {
* typia.assert<IMember>({ name: "John", age: 18 });
* } catch (error) {
* if (error instanceof TypeGuardError) {
* console.log(error.method); // "typia.assert"
* console.log(error.path); // "input.age"
* console.log(error.expected); // "number & ExclusiveMinimum<19>"
* console.log(error.value); // 18
* }
* }
* ```
*/
export class TypeGuardError<T = any> extends Error {
/**
* The name of the typia method that threw this error.
*
* @example "typia.assert"
*/
public readonly method: string;
/**
* The access path to the property where the assertion error occurred.
*
* Uses dot notation to indicate the path for nested object properties.
* May be `undefined` if the error occurred at the root level.
*
* @example
* - `"input.age"` - Error in the age property of the object
* - `"input.profile.email"` - Error in the email property of a nested object
* - `"input[0].name"` - Error in the name property of the first array element
* - `undefined` - Error occurred at the root level
*/
public readonly path: string | undefined;
/**
* String representation of the expected type at the error location.
*
* Represents TypeScript types as strings, including detailed type information
* for complex types.
*
* @example
* - `"string"` - Expected string type
* - `"number & ExclusiveMinimum<19>"` - Expected number greater than 19
* - `"undefined"` - Expected undefined (when superfluous property found in assertion)
* - `"{ name: string; age: number }"` - Expected object type
*/
public readonly expected: string;
/**
* The actual value that failed assertion.
*
* Stores the actual value at the error path as-is.
* Useful for debugging by comparing the expected type with the actual value.
*
* @example
* - `18` - Numeric value
* - `"invalid"` - String value
* - `{ name: "John", age: 18, sex: 1 }` - Object value
*/
public readonly value: any;
/**
* Phantom property for type safety purposes.
*
* This property is not actually used and exists only to maintain
* the generic type T in TypeScript's type system.
* Always has an `undefined` value at runtime.
*
* @internal
*/
protected readonly fake_expected_typed_value_?: T | undefined;
/**
* Creates a new TypeGuardError instance.
*
* @param props - Object containing the properties needed to create the error
*
* @example
* ```typescript
* const error = new TypeGuardError({
* method: "typia.assert",
* path: "input.age",
* expected: "number & ExclusiveMinimum<19>",
* value: 18
* });
* ```
*/
public constructor(props: TypeGuardError.IProps) {
// MESSAGE CONSTRUCTION
// Use custom message if provided, otherwise generate default format
super(
props.message ||
`Error on ${props.method}(): invalid type${
props.path ? ` on ${props.path}` : ""
}, expect to be ${props.expected}`,
);
// INHERITANCE POLYFILL
// Set up prototype for compatibility across different JavaScript environments
const proto = new.target.prototype;
if (Object.setPrototypeOf) Object.setPrototypeOf(this, proto);
else (this as any).__proto__ = proto;
// ASSIGN MEMBERS
this.method = props.method;
this.path = props.path;
this.expected = props.expected;
this.value = props.value;
}
}
export namespace TypeGuardError {
/**
* Interface for properties passed to the TypeGuardError constructor.
*
* @example
* ```typescript
* const props: TypeGuardError.IProps = {
* method: "typia.assertEquals",
* path: "input.sex",
* expected: "undefined",
* value: 1,
* message: "Custom error message" // optional
* };
* ```
*/
export interface IProps {
/**
* The name of the typia method that threw the error.
*
* @example "typia.assert", "typia.assertEquals"
*/
method: string;
/**
* The access path to the property where the assertion error occurred (optional).
*
* @example "input.age", "input.profile.email"
*/
path?: undefined | string;
/**
* String representation of the expected type at the error location.
*
* @example "string", "number & ExclusiveMinimum<19>"
*/
expected: string;
/**
* The actual value that failed assertion.
*/
value: any;
/**
* Custom error message (optional).
*
* If not provided, a default format message will be automatically generated.
*/
message?: undefined | string;
}
}
undefined
/**
* Union type representing the result of type validation
*
* This is the return type of {@link typia.validate} functions, returning
* {@link IValidation.ISuccess} on validation success and
* {@link IValidation.IFailure} on validation failure. When validation fails, it
* provides detailed, granular error information that precisely describes what
* went wrong, where it went wrong, and what was expected.
*
* This comprehensive error reporting makes `IValidation` particularly valuable
* for AI function calling scenarios, where Large Language Models (LLMs) need
* specific feedback to correct their parameter generation. The detailed error
* information is used by ILlmFunction.validate() to provide validation feedback
* to AI agents, enabling iterative correction and improvement of function
* calling accuracy.
*
* This type uses the Discriminated Union pattern, allowing type specification
* through the success property:
*
* ```typescript
* const result = typia.validate<string>(input);
* if (result.success) {
* // IValidation.ISuccess<string> type
* console.log(result.data); // validated data accessible
* } else {
* // IValidation.IFailure type
* console.log(result.errors); // detailed error information accessible
* }
* ```
*
* @author Jeongho Nam - https://github.com/samchon
* @template T The type to validate
*/
export type IValidation<T = unknown> =
| IValidation.ISuccess<T>
| IValidation.IFailure;
export namespace IValidation {
/**
* Interface returned when type validation succeeds
*
* Returned when the input value perfectly conforms to the specified type T.
* Since success is true, TypeScript's type guard allows safe access to the
* validated data through the data property.
*
* @template T The validated type
*/
export interface ISuccess<T = unknown> {
/** Indicates validation success */
success: true;
/** The validated data of type T */
data: T;
}
/**
* Interface returned when type validation fails
*
* Returned when the input value does not conform to the expected type.
* Contains comprehensive error information designed to be easily understood
* by both humans and AI systems. Each error in the errors array provides
* precise details about validation failures, including the exact path to the
* problematic property, what type was expected, and what value was actually
* provided.
*
* This detailed error structure is specifically optimized for AI function
* calling validation feedback. When LLMs make type errors during function
* calling, these granular error reports enable the AI to understand exactly
* what went wrong and how to fix it, improving success rates in subsequent
* attempts.
*
* Example error scenarios:
*
* - Type mismatch: expected "string" but got number 5
* - Format violation: expected "string & Format<'uuid'>" but got
* "invalid-format"
* - Missing properties: expected "required property 'name'" but got undefined
* - Array type errors: expected "Array<string>" but got single string value
*
* The errors are used by ILlmFunction.validate() to provide structured
* feedback to AI agents, enabling them to correct their parameter generation
* and achieve improved function calling accuracy.
*/
export interface IFailure {
/** Indicates validation failure */
success: false;
/** The original input data that failed validation */
data: unknown;
/** Array of detailed validation errors */
errors: IError[];
}
/**
* Detailed information about a specific validation error
*
* Each error provides granular, actionable information about validation
* failures, designed to be immediately useful for both human developers and
* AI systems. The error structure follows a consistent format that enables
* precise identification and correction of type mismatches.
*
* This error format is particularly valuable for AI function calling
* scenarios, where LLMs need to understand exactly what went wrong to
* generate correct parameters. The combination of path, expected type, and
* actual value provides the AI with sufficient context to make accurate
* corrections, which is why ILlmFunction.validate() can achieve such high
* success rates in validation feedback loops.
*
* Real-world examples from AI function calling:
*
* {
* path: "input.member.age",
* expected: "number & Format<'uint32'>",
* value: 20.75 // AI provided float instead of uint32
* }
*
* {
* path: "input.categories",
* expected: "Array<string>",
* value: "technology" // AI provided string instead of array
* }
*
* {
* path: "input.id",
* expected: "string & Format<'uuid'>",
* value: "invalid-uuid-format" // AI provided malformed UUID
* }
*/
export interface IError {
/**
* The path to the property that failed validation (e.g.,
* "input.member.age")
*/
path: string;
/** Description of the expected type or format */
expected: string;
/** The actual value that caused the validation failure */
value: any;
}
}
You can boost up JSON serialization speed just by calling typia.json.stringify<T>()
function. Also, you even can ensure type safety of JSON serialization by calling other functions like typia.json.isStringify()
and typia.json.assertStringify()
functions.
As typia.json.stringify<T>()
function writes dedicated JSON serialization code only for the target type T
, its performance is much faster than native JSON.stringify()
function. However, because of the dedicated optimal JSON serialization code, when wrong typed data comes, unexpected error be occurred.
Instead, typia
supports type safe JSON serialization functions like typia.json.isStringify()
. The typia.json.isStringify()
is a combination function of typia.is<T>()
and typia.json.stringify<T>()
function. It checks whether the input value is valid for the target type T
or not first, and operate JSON serialization later. If the input value is not matched with the type T
, it returns null
value.
typia.json.isStringify()
:typia.is<T>()
+typia.json.stringify<T>()
typia.json.assertStringify()
:typia.assert<T>()
+typia.json.stringify<T>()
typia.json.validateStringify()
:typia.validate<T>()
+typia.json.stringify<T>()
AOT compilation
typia.json.isStringify()
and other similar functions are still much faster than native JSON.stringify()
function, even though they include type checking process. This is the power of AOT compilation, writing optimal dedicated code by analyzing TypeScript type, in the compilation level.
TypeScript Source Code
import typia, { tags } from "typia";
const department: IDepartment = typia.random<IDepartment>();
const json: string | null = typia.json.isStringify(department);
console.log(json); // not null, but string
interface IDepartment {
id: string & tags.Format<"uuid">;
name: string & tags.MinLength<3>;
limit: number & tags.Type<"int32">;
clerks: IClerk[];
}
interface IClerk {
name: string;
age: number &
tags.Type<"uint32"> &
tags.ExclusiveMinimum<19> &
tags.Maximum<100>;
authority: number;
joined_at: string & tags.Format<"date">;
}
Compiled JavaScript File
import typia from "typia";
import * as __typia_transform__isFormatDate from "typia/lib/internal/_isFormatDate.js";
import * as __typia_transform__isFormatUuid from "typia/lib/internal/_isFormatUuid.js";
import * as __typia_transform__isTypeInt32 from "typia/lib/internal/_isTypeInt32.js";
import * as __typia_transform__isTypeUint32 from "typia/lib/internal/_isTypeUint32.js";
import * as __typia_transform__jsonStringifyNumber from "typia/lib/internal/_jsonStringifyNumber.js";
import * as __typia_transform__jsonStringifyString from "typia/lib/internal/_jsonStringifyString.js";
import * as __typia_transform__randomArray from "typia/lib/internal/_randomArray.js";
import * as __typia_transform__randomFormatDate from "typia/lib/internal/_randomFormatDate.js";
import * as __typia_transform__randomFormatUuid from "typia/lib/internal/_randomFormatUuid.js";
import * as __typia_transform__randomInteger from "typia/lib/internal/_randomInteger.js";
import * as __typia_transform__randomNumber from "typia/lib/internal/_randomNumber.js";
import * as __typia_transform__randomString from "typia/lib/internal/_randomString.js";
const department = (() => {
const _ro0 = (_recursive = false, _depth = 0) => ({
id: (
_generator?.uuid ?? __typia_transform__randomFormatUuid._randomFormatUuid
)(),
name: (_generator?.string ?? __typia_transform__randomString._randomString)(
{
type: "string",
minLength: 3,
},
),
limit: (
_generator?.integer ?? __typia_transform__randomInteger._randomInteger
)({
type: "integer",
}),
clerks: (_generator?.array ?? __typia_transform__randomArray._randomArray)({
type: "array",
element: () => _ro1(_recursive, _recursive ? 1 + _depth : _depth),
}),
});
const _ro1 = (_recursive = false, _depth = 0) => ({
name: (_generator?.string ?? __typia_transform__randomString._randomString)(
{
type: "string",
},
),
age: (
_generator?.integer ?? __typia_transform__randomInteger._randomInteger
)({
type: "integer",
minimum: 0,
exclusiveMinimum: 19,
maximum: 100,
}),
authority: (
_generator?.number ?? __typia_transform__randomNumber._randomNumber
)({
type: "number",
}),
joined_at: (
_generator?.date ?? __typia_transform__randomFormatDate._randomFormatDate
)(),
});
let _generator;
return (generator) => {
_generator = generator;
return _ro0();
};
})()();
const json = (() => {
const _io0 = (input) =>
"string" === typeof input.id &&
__typia_transform__isFormatUuid._isFormatUuid(input.id) &&
"string" === typeof input.name &&
3 <= input.name.length &&
"number" === typeof input.limit &&
__typia_transform__isTypeInt32._isTypeInt32(input.limit) &&
Array.isArray(input.clerks) &&
input.clerks.every(
(elem) => "object" === typeof elem && null !== elem && _io1(elem),
);
const _io1 = (input) =>
"string" === typeof input.name &&
"number" === typeof input.age &&
__typia_transform__isTypeUint32._isTypeUint32(input.age) &&
19 < input.age &&
input.age <= 100 &&
"number" === typeof input.authority &&
Number.isFinite(input.authority) &&
"string" === typeof input.joined_at &&
__typia_transform__isFormatDate._isFormatDate(input.joined_at);
const _so0 = (input) =>
`{"id":${__typia_transform__jsonStringifyString._jsonStringifyString(input.id)},"name":${__typia_transform__jsonStringifyString._jsonStringifyString(input.name)},"limit":${__typia_transform__jsonStringifyNumber._jsonStringifyNumber(input.limit)},"clerks":${`[${input.clerks.map((elem) => _so1(elem)).join(",")}]`}}`;
const _so1 = (input) =>
`{"name":${__typia_transform__jsonStringifyString._jsonStringifyString(input.name)},"age":${__typia_transform__jsonStringifyNumber._jsonStringifyNumber(input.age)},"authority":${__typia_transform__jsonStringifyNumber._jsonStringifyNumber(input.authority)},"joined_at":${__typia_transform__jsonStringifyString._jsonStringifyString(input.joined_at)}}`;
const __is = (input) =>
"object" === typeof input && null !== input && _io0(input);
const __stringify = (input) => _so0(input);
return (input) => (__is(input) ? __stringify(input) : null);
})()(department);
console.log(json); // not null, but string
Reusable functions
undefined
export namespace json {
export function createStringify<T>(): (input: T) => string;
export function createIsStringify<T>(): (input: unknown) => string | null;
export function createAssertStringify<T>(
errorFactory?: undefined | ((props: TypeGuardError.IProps) => Error),
): (input: unknown) => string;
export function createValidateStringify<T>(): (input: unknown) => IValidation<string>;
}
undefined
/**
* Custom error class thrown when runtime assertion fails in `typia.assert<T>()` function.
*
* This error is thrown by the `typia.assert<T>()` function when the input value
* doesn't match the expected type.
*
* The error provides detailed information about the first assertion failure encountered,
* including the access path where the error occurred, the expected type, and the actual value.
*
* @template T - The expected type (generic for type safety)
* @author Jeongho Nam - https://github.com/samchon
* @example
* ```typescript
* interface IMember {
* name: string;
* age: number & ExclusiveMinimum<19>;
* }
*
* try {
* typia.assert<IMember>({ name: "John", age: 18 });
* } catch (error) {
* if (error instanceof TypeGuardError) {
* console.log(error.method); // "typia.assert"
* console.log(error.path); // "input.age"
* console.log(error.expected); // "number & ExclusiveMinimum<19>"
* console.log(error.value); // 18
* }
* }
* ```
*/
export class TypeGuardError<T = any> extends Error {
/**
* The name of the typia method that threw this error.
*
* @example "typia.assert"
*/
public readonly method: string;
/**
* The access path to the property where the assertion error occurred.
*
* Uses dot notation to indicate the path for nested object properties.
* May be `undefined` if the error occurred at the root level.
*
* @example
* - `"input.age"` - Error in the age property of the object
* - `"input.profile.email"` - Error in the email property of a nested object
* - `"input[0].name"` - Error in the name property of the first array element
* - `undefined` - Error occurred at the root level
*/
public readonly path: string | undefined;
/**
* String representation of the expected type at the error location.
*
* Represents TypeScript types as strings, including detailed type information
* for complex types.
*
* @example
* - `"string"` - Expected string type
* - `"number & ExclusiveMinimum<19>"` - Expected number greater than 19
* - `"undefined"` - Expected undefined (when superfluous property found in assertion)
* - `"{ name: string; age: number }"` - Expected object type
*/
public readonly expected: string;
/**
* The actual value that failed assertion.
*
* Stores the actual value at the error path as-is.
* Useful for debugging by comparing the expected type with the actual value.
*
* @example
* - `18` - Numeric value
* - `"invalid"` - String value
* - `{ name: "John", age: 18, sex: 1 }` - Object value
*/
public readonly value: any;
/**
* Phantom property for type safety purposes.
*
* This property is not actually used and exists only to maintain
* the generic type T in TypeScript's type system.
* Always has an `undefined` value at runtime.
*
* @internal
*/
protected readonly fake_expected_typed_value_?: T | undefined;
/**
* Creates a new TypeGuardError instance.
*
* @param props - Object containing the properties needed to create the error
*
* @example
* ```typescript
* const error = new TypeGuardError({
* method: "typia.assert",
* path: "input.age",
* expected: "number & ExclusiveMinimum<19>",
* value: 18
* });
* ```
*/
public constructor(props: TypeGuardError.IProps) {
// MESSAGE CONSTRUCTION
// Use custom message if provided, otherwise generate default format
super(
props.message ||
`Error on ${props.method}(): invalid type${
props.path ? ` on ${props.path}` : ""
}, expect to be ${props.expected}`,
);
// INHERITANCE POLYFILL
// Set up prototype for compatibility across different JavaScript environments
const proto = new.target.prototype;
if (Object.setPrototypeOf) Object.setPrototypeOf(this, proto);
else (this as any).__proto__ = proto;
// ASSIGN MEMBERS
this.method = props.method;
this.path = props.path;
this.expected = props.expected;
this.value = props.value;
}
}
export namespace TypeGuardError {
/**
* Interface for properties passed to the TypeGuardError constructor.
*
* @example
* ```typescript
* const props: TypeGuardError.IProps = {
* method: "typia.assertEquals",
* path: "input.sex",
* expected: "undefined",
* value: 1,
* message: "Custom error message" // optional
* };
* ```
*/
export interface IProps {
/**
* The name of the typia method that threw the error.
*
* @example "typia.assert", "typia.assertEquals"
*/
method: string;
/**
* The access path to the property where the assertion error occurred (optional).
*
* @example "input.age", "input.profile.email"
*/
path?: undefined | string;
/**
* String representation of the expected type at the error location.
*
* @example "string", "number & ExclusiveMinimum<19>"
*/
expected: string;
/**
* The actual value that failed assertion.
*/
value: any;
/**
* Custom error message (optional).
*
* If not provided, a default format message will be automatically generated.
*/
message?: undefined | string;
}
}
undefined
/**
* Union type representing the result of type validation
*
* This is the return type of {@link typia.validate} functions, returning
* {@link IValidation.ISuccess} on validation success and
* {@link IValidation.IFailure} on validation failure. When validation fails, it
* provides detailed, granular error information that precisely describes what
* went wrong, where it went wrong, and what was expected.
*
* This comprehensive error reporting makes `IValidation` particularly valuable
* for AI function calling scenarios, where Large Language Models (LLMs) need
* specific feedback to correct their parameter generation. The detailed error
* information is used by ILlmFunction.validate() to provide validation feedback
* to AI agents, enabling iterative correction and improvement of function
* calling accuracy.
*
* This type uses the Discriminated Union pattern, allowing type specification
* through the success property:
*
* ```typescript
* const result = typia.validate<string>(input);
* if (result.success) {
* // IValidation.ISuccess<string> type
* console.log(result.data); // validated data accessible
* } else {
* // IValidation.IFailure type
* console.log(result.errors); // detailed error information accessible
* }
* ```
*
* @author Jeongho Nam - https://github.com/samchon
* @template T The type to validate
*/
export type IValidation<T = unknown> =
| IValidation.ISuccess<T>
| IValidation.IFailure;
export namespace IValidation {
/**
* Interface returned when type validation succeeds
*
* Returned when the input value perfectly conforms to the specified type T.
* Since success is true, TypeScript's type guard allows safe access to the
* validated data through the data property.
*
* @template T The validated type
*/
export interface ISuccess<T = unknown> {
/** Indicates validation success */
success: true;
/** The validated data of type T */
data: T;
}
/**
* Interface returned when type validation fails
*
* Returned when the input value does not conform to the expected type.
* Contains comprehensive error information designed to be easily understood
* by both humans and AI systems. Each error in the errors array provides
* precise details about validation failures, including the exact path to the
* problematic property, what type was expected, and what value was actually
* provided.
*
* This detailed error structure is specifically optimized for AI function
* calling validation feedback. When LLMs make type errors during function
* calling, these granular error reports enable the AI to understand exactly
* what went wrong and how to fix it, improving success rates in subsequent
* attempts.
*
* Example error scenarios:
*
* - Type mismatch: expected "string" but got number 5
* - Format violation: expected "string & Format<'uuid'>" but got
* "invalid-format"
* - Missing properties: expected "required property 'name'" but got undefined
* - Array type errors: expected "Array<string>" but got single string value
*
* The errors are used by ILlmFunction.validate() to provide structured
* feedback to AI agents, enabling them to correct their parameter generation
* and achieve improved function calling accuracy.
*/
export interface IFailure {
/** Indicates validation failure */
success: false;
/** The original input data that failed validation */
data: unknown;
/** Array of detailed validation errors */
errors: IError[];
}
/**
* Detailed information about a specific validation error
*
* Each error provides granular, actionable information about validation
* failures, designed to be immediately useful for both human developers and
* AI systems. The error structure follows a consistent format that enables
* precise identification and correction of type mismatches.
*
* This error format is particularly valuable for AI function calling
* scenarios, where LLMs need to understand exactly what went wrong to
* generate correct parameters. The combination of path, expected type, and
* actual value provides the AI with sufficient context to make accurate
* corrections, which is why ILlmFunction.validate() can achieve such high
* success rates in validation feedback loops.
*
* Real-world examples from AI function calling:
*
* {
* path: "input.member.age",
* expected: "number & Format<'uint32'>",
* value: 20.75 // AI provided float instead of uint32
* }
*
* {
* path: "input.categories",
* expected: "Array<string>",
* value: "technology" // AI provided string instead of array
* }
*
* {
* path: "input.id",
* expected: "string & Format<'uuid'>",
* value: "invalid-uuid-format" // AI provided malformed UUID
* }
*/
export interface IError {
/**
* The path to the property that failed validation (e.g.,
* "input.member.age")
*/
path: string;
/** Description of the expected type or format */
expected: string;
/** The actual value that caused the validation failure */
value: any;
}
}
Reusable typia.json.stringify<T>()
function generators.
If you repeat to call typia.json.stringify<T>()
function on the same type, size of JavaScript files would be larger because of duplicated AOT compilation. To prevent it, you can generate reusable function through typia.json.createStringify<T>()
function.
Just look at the code below, then you may understand how to use it.
TypeScript Source Code
import typia, { tags } from "typia";
export const assertDepartment = typia.json.createAssertStringify<IDepartment>();
interface IDepartment {
id: string & tags.Format<"uuid">;
name: string & tags.MinLength<3>;
limit: number & tags.Type<"int32">;
clerks: IClerk[];
}
interface IClerk {
name: string;
age: number &
tags.Type<"uint32"> &
tags.ExclusiveMinimum<19> &
tags.Maximum<100>;
authority: number;
joined_at: string & tags.Format<"date">;
}
Compiled JavaScript File
import typia from "typia";
import * as __typia_transform__assertGuard from "typia/lib/internal/_assertGuard.js";
import * as __typia_transform__isFormatDate from "typia/lib/internal/_isFormatDate.js";
import * as __typia_transform__isFormatUuid from "typia/lib/internal/_isFormatUuid.js";
import * as __typia_transform__isTypeInt32 from "typia/lib/internal/_isTypeInt32.js";
import * as __typia_transform__isTypeUint32 from "typia/lib/internal/_isTypeUint32.js";
import * as __typia_transform__jsonStringifyNumber from "typia/lib/internal/_jsonStringifyNumber.js";
import * as __typia_transform__jsonStringifyString from "typia/lib/internal/_jsonStringifyString.js";
export const assertDepartment = (() => {
const _io0 = (input) =>
"string" === typeof input.id &&
__typia_transform__isFormatUuid._isFormatUuid(input.id) &&
"string" === typeof input.name &&
3 <= input.name.length &&
"number" === typeof input.limit &&
__typia_transform__isTypeInt32._isTypeInt32(input.limit) &&
Array.isArray(input.clerks) &&
input.clerks.every(
(elem) => "object" === typeof elem && null !== elem && _io1(elem),
);
const _io1 = (input) =>
"string" === typeof input.name &&
"number" === typeof input.age &&
__typia_transform__isTypeUint32._isTypeUint32(input.age) &&
19 < input.age &&
input.age <= 100 &&
"number" === typeof input.authority &&
Number.isFinite(input.authority) &&
"string" === typeof input.joined_at &&
__typia_transform__isFormatDate._isFormatDate(input.joined_at);
const _ao0 = (input, _path, _exceptionable = true) =>
(("string" === typeof input.id &&
(__typia_transform__isFormatUuid._isFormatUuid(input.id) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.json.createAssertStringify",
path: _path + ".id",
expected: 'string & Format<"uuid">',
value: input.id,
},
_errorFactory,
))) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.json.createAssertStringify",
path: _path + ".id",
expected: '(string & Format<"uuid">)',
value: input.id,
},
_errorFactory,
)) &&
(("string" === typeof input.name &&
(3 <= input.name.length ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.json.createAssertStringify",
path: _path + ".name",
expected: "string & MinLength<3>",
value: input.name,
},
_errorFactory,
))) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.json.createAssertStringify",
path: _path + ".name",
expected: "(string & MinLength<3>)",
value: input.name,
},
_errorFactory,
)) &&
(("number" === typeof input.limit &&
(__typia_transform__isTypeInt32._isTypeInt32(input.limit) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.json.createAssertStringify",
path: _path + ".limit",
expected: 'number & Type<"int32">',
value: input.limit,
},
_errorFactory,
))) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.json.createAssertStringify",
path: _path + ".limit",
expected: '(number & Type<"int32">)',
value: input.limit,
},
_errorFactory,
)) &&
(((Array.isArray(input.clerks) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.json.createAssertStringify",
path: _path + ".clerks",
expected: "Array<IClerk>",
value: input.clerks,
},
_errorFactory,
)) &&
input.clerks.every(
(elem, _index2) =>
((("object" === typeof elem && null !== elem) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.json.createAssertStringify",
path: _path + ".clerks[" + _index2 + "]",
expected: "IClerk",
value: elem,
},
_errorFactory,
)) &&
_ao1(
elem,
_path + ".clerks[" + _index2 + "]",
true && _exceptionable,
)) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.json.createAssertStringify",
path: _path + ".clerks[" + _index2 + "]",
expected: "IClerk",
value: elem,
},
_errorFactory,
),
)) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.json.createAssertStringify",
path: _path + ".clerks",
expected: "Array<IClerk>",
value: input.clerks,
},
_errorFactory,
));
const _ao1 = (input, _path, _exceptionable = true) =>
("string" === typeof input.name ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.json.createAssertStringify",
path: _path + ".name",
expected: "string",
value: input.name,
},
_errorFactory,
)) &&
(("number" === typeof input.age &&
(__typia_transform__isTypeUint32._isTypeUint32(input.age) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.json.createAssertStringify",
path: _path + ".age",
expected: 'number & Type<"uint32">',
value: input.age,
},
_errorFactory,
)) &&
(19 < input.age ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.json.createAssertStringify",
path: _path + ".age",
expected: "number & ExclusiveMinimum<19>",
value: input.age,
},
_errorFactory,
)) &&
(input.age <= 100 ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.json.createAssertStringify",
path: _path + ".age",
expected: "number & Maximum<100>",
value: input.age,
},
_errorFactory,
))) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.json.createAssertStringify",
path: _path + ".age",
expected:
'(number & Type<"uint32"> & ExclusiveMinimum<19> & Maximum<100>)',
value: input.age,
},
_errorFactory,
)) &&
(("number" === typeof input.authority &&
Number.isFinite(input.authority)) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.json.createAssertStringify",
path: _path + ".authority",
expected: "number",
value: input.authority,
},
_errorFactory,
)) &&
(("string" === typeof input.joined_at &&
(__typia_transform__isFormatDate._isFormatDate(input.joined_at) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.json.createAssertStringify",
path: _path + ".joined_at",
expected: 'string & Format<"date">',
value: input.joined_at,
},
_errorFactory,
))) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.json.createAssertStringify",
path: _path + ".joined_at",
expected: '(string & Format<"date">)',
value: input.joined_at,
},
_errorFactory,
));
const _so0 = (input) =>
`{"id":${__typia_transform__jsonStringifyString._jsonStringifyString(input.id)},"name":${__typia_transform__jsonStringifyString._jsonStringifyString(input.name)},"limit":${__typia_transform__jsonStringifyNumber._jsonStringifyNumber(input.limit)},"clerks":${`[${input.clerks.map((elem) => _so1(elem)).join(",")}]`}}`;
const _so1 = (input) =>
`{"name":${__typia_transform__jsonStringifyString._jsonStringifyString(input.name)},"age":${__typia_transform__jsonStringifyNumber._jsonStringifyNumber(input.age)},"authority":${__typia_transform__jsonStringifyNumber._jsonStringifyNumber(input.authority)},"joined_at":${__typia_transform__jsonStringifyString._jsonStringifyString(input.joined_at)}}`;
const __is = (input) =>
"object" === typeof input && null !== input && _io0(input);
let _errorFactory;
const __assert = (input, errorFactory) => {
if (false === __is(input)) {
_errorFactory = errorFactory;
((input, _path, _exceptionable = true) =>
((("object" === typeof input && null !== input) ||
__typia_transform__assertGuard._assertGuard(
true,
{
method: "typia.json.createAssertStringify",
path: _path + "",
expected: "IDepartment",
value: input,
},
_errorFactory,
)) &&
_ao0(input, _path + "", true)) ||
__typia_transform__assertGuard._assertGuard(
true,
{
method: "typia.json.createAssertStringify",
path: _path + "",
expected: "IDepartment",
value: input,
},
_errorFactory,
))(input, "$input", true);
}
return input;
};
const __stringify = (input) => _so0(input);
return (input, errorFactory) => {
__assert(input, errorFactory);
return __stringify(input);
};
})();
Performance
Comparing JSON serialization speed with others, it is maximum 200x faster than class-transformer
.
For reference, class-transformer
is the most famous library used in NestJS
with class-validator
. Also, fast-json-stringify
is another famous one used in fastify
. However, whether they are fast or slow, both of them require extra schema definition, that is different with TypeScript type. If you see the code below without experience of them, you may get shocked: how complicate and inefficient they are:
fast-json-stringify
requires JSON schema definition .class-validator
requires DTO class with decorator function calls .
Measured on AMD Ryzen 9 7940HS, Rog Flow x13 
Server Performance
Someone may ask:
JSON serialization speed affects on the server performance?
I think that the JSON serialization is just a tiny thing in the server side, isn’t it?
My answer is, “Yes, it affects on the server performance”.
Most operations in NodeJS server are asynchronously executed in background thread, what are called “event based non-blocking I/O model”. However, JSON serialization is a synchronous operation running on the main thread. Therefore, if the JSON serialization speed is slow, it makes the entire server program slow.
I’ll show you the benchmark result that, how JSON serizliation speed affects on the server performance.
Measured on AMD Ryzen 9 7940HS, Rog Flow x13