validate() function

export function validate<T>(input: T): IValidation<T>;
export function validate<T>(input: unknown): IValidation<T>;

Validates a value type.

typia.validate<T>() function validates input value type, and archives every type errors detaily into IValidation.IFailure.errors array, when the input value is not following the promised type T. Of course, if the parametric input value is following the type T, IValidation.ISuccess instance would be returned.

In the below example case, as id and age values are different with its definition of IMember, such errors would be archived into the IValidation.IFailure.errors array.

  • errors[0]
    • path: input.id
    • expected: string & Format<"uuid">
    • value: 5
  • errors[1]
    • path: input.age
    • expected: number & Format<"uint32">
    • value: 20.75

examples/src/validate.ts
import typia, { tags } from "typia";
 
const res: typia.IValidation<IMember> = typia.validate<IMember>({
  id: 5, // wrong, must be string (uuid)
  age: 20.75, // wrong, not integer
  email: "samchon.github@gmail.com",
});
 
if (!res.success) console.log(res.errors);
 
interface IMember {
  id: string & tags.Format<"uuid">;
  email: string & tags.Format<"email">;
  age: number &
    tags.Type<"uint32"> &
    tags.ExclusiveMinimum<19> &
    tags.Maximum<100>;
}

validateEquals() function

export function validateEquals<T>(input: T): IValidation<T>;
export function validateEquals<T>(input: unknown): IValidation<T>;

More strict validatae function prohibiting superfluous properties.

typia.validate<T> function detects every type errors of input value, however, it can’t detect superfluous properties. If you want to prohibit those superfluous properties, so that archive them into IValidation.IFailure.errors array, use typia.validateEquals<T>() function instead.

In the below example case, as id property is different with its type definition and sex property is not defined in the IMember type, such errors would be archived into the IValidation.IFailure.errors array:

  • errors[0]
    • path: input.id
    • expected: string (@format uuid)
    • value: something
  • errors[1]
    • path: input.sex
    • expected: undefined
    • value: 1
examples/src/validateEquals.ts
import typia, { tags } from "typia";
 
const res: typia.IValidation<IMember> = typia.validateEquals<IMember>({
  age: 30,
  email: "samchon.github@gmail.com",
  id: "something", // wrong, must be string (uuid)
  sex: 1, // extra property
});
 
if (!res.success) console.log(res.errors);
 
interface IMember {
  id: string & tags.Format<"uuid">;
  email: string & tags.Format<"email">;
  age: number &
    tags.Type<"uint32"> &
    tags.ExclusiveMinimum<19> &
    tags.Maximum<100>;
}

Reusable functions

export function createValidate<T> = (input: unknown) => IValidation<T>;
export function createValidateEquals<T> = (input: unknown) => IValidation<T>;

Reusable typia.validate<T>() function generators.

If you repeat to call typia.validate<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.createValidate<T>() function.

Just look at the code below, then you may understand how to use it.

examples/src/createValidate.ts
import typia, { tags } from "typia";
 
export const validateMember = typia.createValidate<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.validate<T>() function does not check function and user-defined class types.

It validates only the primitive properties. Therefore, typia.validate<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.validate<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.validate<T>() function validates them. Especially about the Set<T>, and Map<Key, T> class cases, typia.validate<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>>();

Discriminated Union

export type IValidation<T> = IValidation.ISuccess<T> | IValidation.IFailure;
export namespace IValidation {
  export interface ISuccess<T> {
    success: true;
    data: T;
  }
  export interface IFailure {
    success: false;
    errors: IError[];
    data: unknown;
  }
  export interface IError {
    path: string;
    expected: string;
    value: any;
  }
}

Specify type through if condition.

typia.IValidation<T> is an union type of typia.IValidation.ISuccess<T> and typia.IValidation.IFailure. Also, they have a common property success of boolean type, but different literal values. In that case, if you write a if condition about the success property, you can specify the union type like below.

In TypeScript, such union type specification through common property (of different literal value() is called β€œDiscriminated Union”. Therefore, when using typia.validate<T>() function, let’s utilize such discriminated union specification for convenience.

import typia from "typia";
 
const something: unknown = ...;
const result: typia.IValidation<string> = typia.validate<string>(something);
 
if (results.success) {
  // become typia.IValidation.Success<string> type
  result.data; // accessible
} else {
  // become typia.IValidation.Failure type
  result.errors; //accessible
}

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/validate-custom-tags.ts
import typia, { tags } from "typia";
 
export const validateSomething = typia.createValidate<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.validate<T>() function with other competitive libraries, maximum 20,000x faster.

Furthermore, only typia can validate complicate union types.

validate 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