πŸ“– Guide DocumentsRuntime Validatorsassert() function

assert() function

export function assert<T>(input: T): T;
export function assert<T>(input: unknown): T;

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>

examples/src/assert.ts
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>;
}

assertEquals() function

export function assertEquals<T>(input: T): T;
export function assertEquals<T>(input: unknown): T;

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
examples/src/assert.ts
import typia, { tags } from "typia";
import { v4 } from "uuid";
 
typia.assert<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>;
}

assertGuard() functions

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;

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.

examples/src/assertGuard.ts
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

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>;

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.

examples/src/createAssert.ts
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>;
}

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.

tsconfig.json
{
  "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.

examples/src/is-map.ts
import typia from "typia";
 
typia.createIs<Map<string, boolean | number | string>>();

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:

examples/src/assert-custom-tags.ts
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>;
}

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.

Assert Function Benchmark

Measured on AMD Ryzen 9 7940HS, Rog Flow x13

ComponentstypiaTypeBoxajvio-tszodC.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. means class-validator