assert()
function
undefined
export function assert<T>(input: T): T;
export function assert<T>(input: unknown): T;
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.
*
* @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
* }
* }
* ```;
*
* @template T - The expected type (generic for type safety)
*/
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: unknown;
/**
* Optional human-readable description of the type guard error
*
* This field is rarely populated in standard typia type assertion and is
* primarily intended for specialized AI agent libraries or custom validation
* scenarios that require additional context beyond the technical type
* information. Most assertion errors rely solely on the path, expected, and
* value fields for comprehensive error reporting.
*/
public readonly description?: string | undefined;
/**
* 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.
*
* @example
* ```typescript
* const error = new TypeGuardError({
* method: "typia.assert",
* path: "input.age",
* expected: "number & ExclusiveMinimum<19>",
* value: 18
* });
* ```;
*
* @param props - Object containing the properties needed to create the error
*/
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;
if (props.description || props.value === undefined)
this.description =
props.description ??
[
"The value at this path is `undefined`.",
"",
`Please fill the \`${props.expected}\` typed value next time.`,
].join("\n");
}
}
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: unknown;
/**
* Optional human-readable description of the type guard error
*
* This field is rarely populated in standard typia type assertion and is
* primarily intended for specialized AI agent libraries or custom
* validation scenarios that require additional context beyond the technical
* type information. Most assertion errors rely solely on the path,
* expected, and value fields for comprehensive error reporting.
*/
description?: string;
/**
* Custom error message (optional).
*
* If not provided, a default format message will be automatically
* generated.
*/
message?: undefined | string;
}
}
Asserts a value type.
typia.assert<T>()
function throws a TypeGuardError
when wrong type comes.
The TypeGuardError
instance has only the first type error info, with access path and expected type. In the below example case, as the age
property is wrong with its definition (@exclusiveMinimum
), such TypeGuardError
would be thrown:
method
:typia.assert()
path
:input.age
value
:18
,expected
:number & ExclusiveMinimum<19>
AOT compilation
If you’d used other competitive validator libraries like ajv
or class-validator
, you may found that typia
does not require any extra schema definition. If you have not experienced them, I can sure that you may get shocked after reading below extra schema definition files.
ajv
requires JSON schema definition .class-validator
requires DTO class with decorator function calls .
Yeah, typia
needs only pure TypeScript type. As typia
is a compiler library, it can analyze TypeScript type by itself, and possible to write the optimal validation code like below. This is the key principle of typia
, which needs only one line with pure TypeScript type.
TypeScript Source Code
import typia, { tags } from "typia";
import { v4 } from "uuid";
typia.assert<IMember>({
id: v4(),
email: "samchon.github@gmail.com",
age: 18, // wrong, must be greater than 19
});
interface IMember {
id: string & tags.Format<"uuid">;
email: string & tags.Format<"email">;
age: number &
tags.Type<"uint32"> &
tags.ExclusiveMinimum<19> &
tags.Maximum<100>;
}
Compiled JavaScript File
import typia from "typia";
import * as __typia_transform__assertGuard from "typia/lib/internal/_assertGuard.js";
import * as __typia_transform__isFormatEmail from "typia/lib/internal/_isFormatEmail.js";
import * as __typia_transform__isFormatUuid from "typia/lib/internal/_isFormatUuid.js";
import * as __typia_transform__isTypeUint32 from "typia/lib/internal/_isTypeUint32.js";
import { v4 } from "uuid";
(() => {
const _io0 = (input) =>
"string" === typeof input.id &&
__typia_transform__isFormatUuid._isFormatUuid(input.id) &&
"string" === typeof input.email &&
__typia_transform__isFormatEmail._isFormatEmail(input.email) &&
"number" === typeof input.age &&
__typia_transform__isTypeUint32._isTypeUint32(input.age) &&
19 < input.age &&
input.age <= 100;
const _ao0 = (input, _path, _exceptionable = true) =>
(("string" === typeof input.id &&
(__typia_transform__isFormatUuid._isFormatUuid(input.id) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.assert",
path: _path + ".id",
expected: 'string & Format<"uuid">',
value: input.id,
},
_errorFactory,
))) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.assert",
path: _path + ".id",
expected: '(string & Format<"uuid">)',
value: input.id,
},
_errorFactory,
)) &&
(("string" === typeof input.email &&
(__typia_transform__isFormatEmail._isFormatEmail(input.email) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.assert",
path: _path + ".email",
expected: 'string & Format<"email">',
value: input.email,
},
_errorFactory,
))) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.assert",
path: _path + ".email",
expected: '(string & Format<"email">)',
value: input.email,
},
_errorFactory,
)) &&
(("number" === typeof input.age &&
(__typia_transform__isTypeUint32._isTypeUint32(input.age) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.assert",
path: _path + ".age",
expected: 'number & Type<"uint32">',
value: input.age,
},
_errorFactory,
)) &&
(19 < input.age ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.assert",
path: _path + ".age",
expected: "number & ExclusiveMinimum<19>",
value: input.age,
},
_errorFactory,
)) &&
(input.age <= 100 ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.assert",
path: _path + ".age",
expected: "number & Maximum<100>",
value: input.age,
},
_errorFactory,
))) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.assert",
path: _path + ".age",
expected:
'(number & Type<"uint32"> & ExclusiveMinimum<19> & Maximum<100>)',
value: input.age,
},
_errorFactory,
));
const __is = (input) =>
"object" === typeof input && null !== input && _io0(input);
let _errorFactory;
return (input, errorFactory) => {
if (false === __is(input)) {
_errorFactory = errorFactory;
((input, _path, _exceptionable = true) =>
((("object" === typeof input && null !== input) ||
__typia_transform__assertGuard._assertGuard(
true,
{
method: "typia.assert",
path: _path + "",
expected: "IMember",
value: input,
},
_errorFactory,
)) &&
_ao0(input, _path + "", true)) ||
__typia_transform__assertGuard._assertGuard(
true,
{
method: "typia.assert",
path: _path + "",
expected: "IMember",
value: input,
},
_errorFactory,
))(input, "$input", true);
}
return input;
};
})()({
id: v4(),
email: "samchon.github@gmail.com",
age: 18, // wrong, must be greater than 19
});
assertEquals()
function
undefined
export function assertEquals<T>(input: T): T;
export function assertEquals<T>(input: unknown): T;
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.
*
* @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
* }
* }
* ```;
*
* @template T - The expected type (generic for type safety)
*/
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: unknown;
/**
* Optional human-readable description of the type guard error
*
* This field is rarely populated in standard typia type assertion and is
* primarily intended for specialized AI agent libraries or custom validation
* scenarios that require additional context beyond the technical type
* information. Most assertion errors rely solely on the path, expected, and
* value fields for comprehensive error reporting.
*/
public readonly description?: string | undefined;
/**
* 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.
*
* @example
* ```typescript
* const error = new TypeGuardError({
* method: "typia.assert",
* path: "input.age",
* expected: "number & ExclusiveMinimum<19>",
* value: 18
* });
* ```;
*
* @param props - Object containing the properties needed to create the error
*/
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;
if (props.description || props.value === undefined)
this.description =
props.description ??
[
"The value at this path is `undefined`.",
"",
`Please fill the \`${props.expected}\` typed value next time.`,
].join("\n");
}
}
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: unknown;
/**
* Optional human-readable description of the type guard error
*
* This field is rarely populated in standard typia type assertion and is
* primarily intended for specialized AI agent libraries or custom
* validation scenarios that require additional context beyond the technical
* type information. Most assertion errors rely solely on the path,
* expected, and value fields for comprehensive error reporting.
*/
description?: string;
/**
* Custom error message (optional).
*
* If not provided, a default format message will be automatically
* generated.
*/
message?: undefined | string;
}
}
More strict assert function prohibiting superfluous properties.
typia.assert<T>()
function inspects input
value type and throws TypeGuardError
when mismatched, however, it can’t detect superfluous properties. If you want to prohibit those superfluous properties, therefore throws an TypeGuardError
when superfluous property exists, use typia.assertEquals<T()>
function instead.
In the below example case, as sex
property is not defined in the IMember
type, such TypeGuardError
would be thrown:
method
:typia.assertEquals()
path
:input.sex
value
:1
,expected
:undefined
TypeScript Source Code
import typia, { tags } from "typia";
import { v4 } from "uuid";
typia.assertEquals<IMember>({
id: v4(),
email: "samchon.github@gmail.com",
age: 30,
sex: 1, // extra
});
interface IMember {
id: string & tags.Format<"uuid">;
email: string & tags.Format<"email">;
age: number &
tags.Type<"uint32"> &
tags.ExclusiveMinimum<19> &
tags.Maximum<100>;
}
Compiled JavaScript File
import typia from "typia";
import * as __typia_transform__accessExpressionAsString from "typia/lib/internal/_accessExpressionAsString.js";
import * as __typia_transform__assertGuard from "typia/lib/internal/_assertGuard.js";
import * as __typia_transform__isFormatEmail from "typia/lib/internal/_isFormatEmail.js";
import * as __typia_transform__isFormatUuid from "typia/lib/internal/_isFormatUuid.js";
import * as __typia_transform__isTypeUint32 from "typia/lib/internal/_isTypeUint32.js";
import { v4 } from "uuid";
(() => {
const _io0 = (input, _exceptionable = true) =>
"string" === typeof input.id &&
__typia_transform__isFormatUuid._isFormatUuid(input.id) &&
"string" === typeof input.email &&
__typia_transform__isFormatEmail._isFormatEmail(input.email) &&
"number" === typeof input.age &&
__typia_transform__isTypeUint32._isTypeUint32(input.age) &&
19 < input.age &&
input.age <= 100 &&
(3 === Object.keys(input).length ||
Object.keys(input).every((key) => {
if (["id", "email", "age"].some((prop) => key === prop)) return true;
const value = input[key];
if (undefined === value) return true;
return false;
}));
const _ao0 = (input, _path, _exceptionable = true) =>
(("string" === typeof input.id &&
(__typia_transform__isFormatUuid._isFormatUuid(input.id) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.assertEquals",
path: _path + ".id",
expected: 'string & Format<"uuid">',
value: input.id,
},
_errorFactory,
))) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.assertEquals",
path: _path + ".id",
expected: '(string & Format<"uuid">)',
value: input.id,
},
_errorFactory,
)) &&
(("string" === typeof input.email &&
(__typia_transform__isFormatEmail._isFormatEmail(input.email) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.assertEquals",
path: _path + ".email",
expected: 'string & Format<"email">',
value: input.email,
},
_errorFactory,
))) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.assertEquals",
path: _path + ".email",
expected: '(string & Format<"email">)',
value: input.email,
},
_errorFactory,
)) &&
(("number" === typeof input.age &&
(__typia_transform__isTypeUint32._isTypeUint32(input.age) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.assertEquals",
path: _path + ".age",
expected: 'number & Type<"uint32">',
value: input.age,
},
_errorFactory,
)) &&
(19 < input.age ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.assertEquals",
path: _path + ".age",
expected: "number & ExclusiveMinimum<19>",
value: input.age,
},
_errorFactory,
)) &&
(input.age <= 100 ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.assertEquals",
path: _path + ".age",
expected: "number & Maximum<100>",
value: input.age,
},
_errorFactory,
))) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.assertEquals",
path: _path + ".age",
expected:
'(number & Type<"uint32"> & ExclusiveMinimum<19> & Maximum<100>)',
value: input.age,
},
_errorFactory,
)) &&
(3 === Object.keys(input).length ||
false === _exceptionable ||
Object.keys(input).every((key) => {
if (["id", "email", "age"].some((prop) => key === prop)) return true;
const value = input[key];
if (undefined === value) return true;
return __typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.assertEquals",
path:
_path +
__typia_transform__accessExpressionAsString._accessExpressionAsString(
key,
),
expected: "undefined",
value: value,
},
_errorFactory,
);
}));
const __is = (input, _exceptionable = true) =>
"object" === typeof input && null !== input && _io0(input, true);
let _errorFactory;
return (input, errorFactory) => {
if (false === __is(input)) {
_errorFactory = errorFactory;
((input, _path, _exceptionable = true) =>
((("object" === typeof input && null !== input) ||
__typia_transform__assertGuard._assertGuard(
true,
{
method: "typia.assertEquals",
path: _path + "",
expected: "IMember",
value: input,
},
_errorFactory,
)) &&
_ao0(input, _path + "", true)) ||
__typia_transform__assertGuard._assertGuard(
true,
{
method: "typia.assertEquals",
path: _path + "",
expected: "IMember",
value: input,
},
_errorFactory,
))(input, "$input", true);
}
return input;
};
})()({
id: v4(),
email: "samchon.github@gmail.com",
age: 30,
sex: 1, // extra
});
assertGuard()
functions
undefined
export function assertGuard<T>(input: T): asserts input is T;
export function assertGuard<T>(input: unknown): asserts input is T;
export function assertGuardEquals<T>(input: T): asserts input is T;
export function assertGuardEquals<T>(input: unknown): asserts input is T;
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.
*
* @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
* }
* }
* ```;
*
* @template T - The expected type (generic for type safety)
*/
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: unknown;
/**
* Optional human-readable description of the type guard error
*
* This field is rarely populated in standard typia type assertion and is
* primarily intended for specialized AI agent libraries or custom validation
* scenarios that require additional context beyond the technical type
* information. Most assertion errors rely solely on the path, expected, and
* value fields for comprehensive error reporting.
*/
public readonly description?: string | undefined;
/**
* 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.
*
* @example
* ```typescript
* const error = new TypeGuardError({
* method: "typia.assert",
* path: "input.age",
* expected: "number & ExclusiveMinimum<19>",
* value: 18
* });
* ```;
*
* @param props - Object containing the properties needed to create the error
*/
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;
if (props.description || props.value === undefined)
this.description =
props.description ??
[
"The value at this path is `undefined`.",
"",
`Please fill the \`${props.expected}\` typed value next time.`,
].join("\n");
}
}
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: unknown;
/**
* Optional human-readable description of the type guard error
*
* This field is rarely populated in standard typia type assertion and is
* primarily intended for specialized AI agent libraries or custom
* validation scenarios that require additional context beyond the technical
* type information. Most assertion errors rely solely on the path,
* expected, and value fields for comprehensive error reporting.
*/
description?: string;
/**
* Custom error message (optional).
*
* If not provided, a default format message will be automatically
* generated.
*/
message?: undefined | string;
}
}
Assertion guard of a value type.
typia.assertGuard<T>()
is similar with typia.assert<T>()
throwing a TypeGuardError
when wrong type.
However, typia.assert<T>()
returns the paramteric input value itself when there’s no type problem on the parametric input value, whereas the typia.assertGuard<T>()
function returns nothing. Instead, the parametric input value would be automatically cased to the type T
. This is the concept of “Assertion Guard” of a value type.
Such similarities and differences of typia.assertGuard<T>()
and typia.assert<T>()
functions are the same in the case of typia.assertGuardEquals<T>()
and typia.assertEquals<T>()
functions. If there’s no type problem on the typia.assertGuardEquals<T>()
function, it also performs the “Assertion Guard”.
Look at the below code, then you may understand what the “Assertion Guard” means.
import typia from "typia";
interface IPoint {
x: number;
y: number;
}
const input: unknown = { x: 1, y: 2 };
// PERFORM THE ASSERTION GUARD
typia.assertGuard<IPoint>(input);
// FROM NOW ON, "input" IS THE "IPoint" TYPE
input.x; // OK
input.y; // OK
Reusable functions
undefined
export function createAssert<T>(): (input: unknown) => T;
export function createAssertEquals<T>(): (input: unknown) => T;
export function createAssertGuard<T>(): AssertionGuard<T>;
export function createAssertGuardEquals<T>(): AssertionGuard<T>;
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.
*
* @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
* }
* }
* ```;
*
* @template T - The expected type (generic for type safety)
*/
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: unknown;
/**
* Optional human-readable description of the type guard error
*
* This field is rarely populated in standard typia type assertion and is
* primarily intended for specialized AI agent libraries or custom validation
* scenarios that require additional context beyond the technical type
* information. Most assertion errors rely solely on the path, expected, and
* value fields for comprehensive error reporting.
*/
public readonly description?: string | undefined;
/**
* 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.
*
* @example
* ```typescript
* const error = new TypeGuardError({
* method: "typia.assert",
* path: "input.age",
* expected: "number & ExclusiveMinimum<19>",
* value: 18
* });
* ```;
*
* @param props - Object containing the properties needed to create the error
*/
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;
if (props.description || props.value === undefined)
this.description =
props.description ??
[
"The value at this path is `undefined`.",
"",
`Please fill the \`${props.expected}\` typed value next time.`,
].join("\n");
}
}
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: unknown;
/**
* Optional human-readable description of the type guard error
*
* This field is rarely populated in standard typia type assertion and is
* primarily intended for specialized AI agent libraries or custom
* validation scenarios that require additional context beyond the technical
* type information. Most assertion errors rely solely on the path,
* expected, and value fields for comprehensive error reporting.
*/
description?: string;
/**
* Custom error message (optional).
*
* If not provided, a default format message will be automatically
* generated.
*/
message?: undefined | string;
}
}
undefined
export type AssertionGuard<T> = (input: unknown) => asserts input is T;
Reusable typia.assert<T>()
function generators.
If you repeat to call typia.assert<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.createAssert<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 assertMember = typia.createAssert<IMember>();
interface IMember {
id: string & tags.Format<"uuid">;
email: string & tags.Format<"email">;
age: number &
tags.Type<"uint32"> &
tags.ExclusiveMinimum<19> &
tags.Maximum<100>;
}
Compiled JavaScript File
import typia from "typia";
import * as __typia_transform__assertGuard from "typia/lib/internal/_assertGuard.js";
import * as __typia_transform__isFormatEmail from "typia/lib/internal/_isFormatEmail.js";
import * as __typia_transform__isFormatUuid from "typia/lib/internal/_isFormatUuid.js";
import * as __typia_transform__isTypeUint32 from "typia/lib/internal/_isTypeUint32.js";
export const assertMember = (() => {
const _io0 = (input) =>
"string" === typeof input.id &&
__typia_transform__isFormatUuid._isFormatUuid(input.id) &&
"string" === typeof input.email &&
__typia_transform__isFormatEmail._isFormatEmail(input.email) &&
"number" === typeof input.age &&
__typia_transform__isTypeUint32._isTypeUint32(input.age) &&
19 < input.age &&
input.age <= 100;
const _ao0 = (input, _path, _exceptionable = true) =>
(("string" === typeof input.id &&
(__typia_transform__isFormatUuid._isFormatUuid(input.id) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.createAssert",
path: _path + ".id",
expected: 'string & Format<"uuid">',
value: input.id,
},
_errorFactory,
))) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.createAssert",
path: _path + ".id",
expected: '(string & Format<"uuid">)',
value: input.id,
},
_errorFactory,
)) &&
(("string" === typeof input.email &&
(__typia_transform__isFormatEmail._isFormatEmail(input.email) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.createAssert",
path: _path + ".email",
expected: 'string & Format<"email">',
value: input.email,
},
_errorFactory,
))) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.createAssert",
path: _path + ".email",
expected: '(string & Format<"email">)',
value: input.email,
},
_errorFactory,
)) &&
(("number" === typeof input.age &&
(__typia_transform__isTypeUint32._isTypeUint32(input.age) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.createAssert",
path: _path + ".age",
expected: 'number & Type<"uint32">',
value: input.age,
},
_errorFactory,
)) &&
(19 < input.age ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.createAssert",
path: _path + ".age",
expected: "number & ExclusiveMinimum<19>",
value: input.age,
},
_errorFactory,
)) &&
(input.age <= 100 ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.createAssert",
path: _path + ".age",
expected: "number & Maximum<100>",
value: input.age,
},
_errorFactory,
))) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.createAssert",
path: _path + ".age",
expected:
'(number & Type<"uint32"> & ExclusiveMinimum<19> & Maximum<100>)',
value: input.age,
},
_errorFactory,
));
const __is = (input) =>
"object" === typeof input && null !== input && _io0(input);
let _errorFactory;
return (input, errorFactory) => {
if (false === __is(input)) {
_errorFactory = errorFactory;
((input, _path, _exceptionable = true) =>
((("object" === typeof input && null !== input) ||
__typia_transform__assertGuard._assertGuard(
true,
{
method: "typia.createAssert",
path: _path + "",
expected: "IMember",
value: input,
},
_errorFactory,
)) &&
_ao0(input, _path + "", true)) ||
__typia_transform__assertGuard._assertGuard(
true,
{
method: "typia.createAssert",
path: _path + "",
expected: "IMember",
value: input,
},
_errorFactory,
))(input, "$input", true);
}
return input;
};
})();
Explicitly of Assertion Guard
Be careful when using typia.createAssertGuard<T>()
or typia.createAssertGuardEquals<T>()
functions.
When calling those functions, you’ve to declare the variable type explicit on the caller variable. If you don’t do it, so that the caller variables come the implicit function type, TypeScript compiler throws an error like below. This is a special limitation of TypeScript compiler about the “Assertion Guard”.
import typia, { AssertionGuard } from "typia";
//MUST DECLARE THE VARIABLE TYPE
const explicit: AssertionGuard<number> = typia.createAssertGuard<number>();
// IF NOT, COMPILATION ERROR BE OCCURRED
const implicit = typia.createAssertGuard<number>();
Restrictions
typia.assert<T>()
function does not check function
and user-defined class
types.
It validates only the primitive properties. Therefore, typia.assert<T>()
function does not perform the instanceof ClassName
for user-defined classes. If you want to validate the user-defined class type in addition to the property types, do it by yourself. Also, typia.assert<T>()
function does not validate the function type either, unless configuring functional
property of plugin
option in the tsconfig.json
file.
{
"compilerOptions": {
"plugins": [
{
"transform": "typia/lib/transform",
"functional": true
}
]
}
}
By the way, there’re some exception cases.
If JS native class type like Date
, Uint8Array
, or Map<Key, T>
being utilized, typia.assert<T>()
function validates them. Especially about the Set<T>
, and Map<Key, T>
class cases, typia.assert<T>()
function validates all of their contained element types, too.
Therefore, the instanceof
statement does not be used only for the user-defined classes.
TypeScript Source Code
import typia from "typia";
typia.createIs<Map<string, boolean | number | string>>();
Compiled JavaScript File
import typia from "typia";
(() => {
return (input) =>
input instanceof Map &&
(() =>
[...input].every(
(elem) =>
Array.isArray(elem) &&
elem.length === 2 &&
"string" === typeof elem[0] &&
("string" === typeof elem[1] ||
("number" === typeof elem[1] && Number.isFinite(elem[1])) ||
"boolean" === typeof elem[1]),
))();
})();
Customization
You can enhance validation logic by special tags.
Also, with those tags, you can add your custom validation logic, too.
If you want to know about such special tags detaily, read below article:
TypeScript Source Code
import typia, { tags } from "typia";
export const assertSomething = typia.createAssert<Something>();
//----
// DEFINE CUSTOM TYPE TAGS
//----
type Dollar = tags.TagBase<{
kind: "dollar";
target: "string";
value: undefined;
validate: `$input[0] === "$" && !isNaN(Number($input.substring(1).split(",").join("")))`;
}>;
type Postfix<Value extends string> = tags.TagBase<{
kind: "postfix";
target: "string";
value: Value;
validate: `$input.endsWith("${Value}")`;
}>;
type IsEven<Value extends number | bigint> = tags.TagBase<{
kind: "isEven";
target: Value extends number ? "number" : "bigint";
value: undefined;
validate: `$input % ${Numeric<2>} === ${Numeric<0>}`;
}>;
type Numeric<Value extends number | bigint> = Value extends number
? Value
: `BigInt(${Value})`;
//----
// VALIDATION
//----
interface Something {
dollar: string & Dollar;
postfix: string & Postfix<"!!!">;
isEven: number & IsEven<number>;
}
Compiled JavaScript File
import typia from "typia";
import * as __typia_transform__assertGuard from "typia/lib/internal/_assertGuard.js";
export const assertSomething = (() => {
const _io0 = (input) =>
"string" === typeof input.dollar &&
input.dollar[0] === "$" &&
!isNaN(Number(input.dollar.substring(1).split(",").join(""))) &&
"string" === typeof input.postfix &&
input.postfix.endsWith("!!!") &&
"number" === typeof input.isEven &&
Number.isFinite(input.isEven) &&
input.isEven % 2 === 0;
const _ao0 = (input, _path, _exceptionable = true) =>
(("string" === typeof input.dollar &&
((input.dollar[0] === "$" &&
!isNaN(Number(input.dollar.substring(1).split(",").join("")))) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.createAssert",
path: _path + ".dollar",
expected: "string & Dollar",
value: input.dollar,
},
_errorFactory,
))) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.createAssert",
path: _path + ".dollar",
expected: "(string & Dollar)",
value: input.dollar,
},
_errorFactory,
)) &&
(("string" === typeof input.postfix &&
(input.postfix.endsWith("!!!") ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.createAssert",
path: _path + ".postfix",
expected: 'string & Postfix<"!!!">',
value: input.postfix,
},
_errorFactory,
))) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.createAssert",
path: _path + ".postfix",
expected: '(string & Postfix<"!!!">)',
value: input.postfix,
},
_errorFactory,
)) &&
(("number" === typeof input.isEven &&
(Number.isFinite(input.isEven) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.createAssert",
path: _path + ".isEven",
expected: "number",
value: input.isEven,
},
_errorFactory,
)) &&
(input.isEven % 2 === 0 ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.createAssert",
path: _path + ".isEven",
expected: "number & IsEven<number>",
value: input.isEven,
},
_errorFactory,
))) ||
__typia_transform__assertGuard._assertGuard(
_exceptionable,
{
method: "typia.createAssert",
path: _path + ".isEven",
expected: "(number & IsEven<number>)",
value: input.isEven,
},
_errorFactory,
));
const __is = (input) =>
"object" === typeof input && null !== input && _io0(input);
let _errorFactory;
return (input, errorFactory) => {
if (false === __is(input)) {
_errorFactory = errorFactory;
((input, _path, _exceptionable = true) =>
((("object" === typeof input && null !== input) ||
__typia_transform__assertGuard._assertGuard(
true,
{
method: "typia.createAssert",
path: _path + "",
expected: "Something",
value: input,
},
_errorFactory,
)) &&
_ao0(input, _path + "", true)) ||
__typia_transform__assertGuard._assertGuard(
true,
{
method: "typia.createAssert",
path: _path + "",
expected: "Something",
value: input,
},
_errorFactory,
))(input, "$input", true);
}
return input;
};
})();
Performance
Super-fast and super-safe.
Comparing typia.assert<T>()
function with other competitive libraries, maximum 20,000x faster.
Furthermore, only typia
can validate complicate union types.
Measured on AMD Ryzen 9 7940HS, Rog Flow x13
Components | typia | TypeBox | ajv | io-ts | zod | C.V. |
---|---|---|---|---|---|---|
Easy to use | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
Object (simple) | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
Object (hierarchical) | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
Object (recursive) | ✔ | ❌ | ✔ | ✔ | ✔ | ✔ |
Object (union, implicit) | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
Object (union, explicit) | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ |
Object (additional tags) | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
Object (template literal types) | ✔ | ✔ | ✔ | ❌ | ❌ | ❌ |
Object (dynamic properties) | ✔ | ✔ | ✔ | ❌ | ❌ | ❌ |
Array (rest tuple) | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
Array (hierarchical) | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
Array (recursive) | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ |
Array (recursive, union) | ✔ | ✔ | ❌ | ✔ | ✔ | ❌ |
Array (R+U, implicit) | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
Array (repeated) | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
Array (repeated, union) | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
Ultimate Union Type | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ |
C.V.
meansclass-validator