đź“– Guide Documents
Random Generator

random() function

export function random<T>(g?: IRandomGenerator): Resolved<T>;

You can make every random data just by calling typia.random<T>() function.

When you call the typia.random<T>() function, typia will analyze your type T, and writes optimal random generation code for the type T, in the compilation level. This is called AOT (Ahead of Time) compliation, and you may understand what it is just by reading below example code.

random.ts
import typia, { tags } from "typia";
 
const member: IMember = typia.random<IMember>();
console.log(member);
 
interface IMember {
  id: string & tags.Format<"uuid">;
  email: string & tags.Format<"email">;
  age: number &
    tags.Type<"uint32"> &
    tags.ExclusiveMinimum<19> &
    tags.Maximum<100>;
}

Reusable function

export function createRandom<T>(): (g?: IRandomGenerator) => Resolved<T>;

Special Tags

Runtime validators of typia provides additional type checking logic through Type Tags and Comment Tags. typia.random<T>() function also like that. typia.random<T>() function can utilize those tags to specialize the behavior of random data generation.

For reference, whether you choose Type Tags or Comment Tags. typia.random<T>(), it is not a matter for typia.random<T>() function. Below two TypeScript codes are generating exactly same JavaScript code. Therefore, you can choose whatever you want considering your preference.

random.tags.ts
import typia, { tags } from "typia";
 
const data: TypeTag = typia.random<TypeTag>();
 
console.log(data);
 
interface TypeTag {
  type: number & tags.Type<"int32">;
  number?: number & tags.ExclusiveMinimum<19> & tags.Maximum<100>;
  string: string & tags.MinLength<3>;
  pattern: string & tags.Pattern<"^[a-z]+$">;
  format: (string & tags.Format<"date-time">) | null;
}

Customization

import { Customizable } from "./typings/Customizable";
 
export interface IRandomGenerator {
  // REGULAR
  boolean(): boolean;
  integer(minimum?: number, maximum?: number): number;
  bigint(minimum?: bigint, maximum?: bigint): bigint;
  number(minimum?: number, maximum?: number): number;
  string(length?: number): string;
 
  array<T>(closure: (index: number) => T, count?: number): T[];
  length(): number;
  pattern(regex: RegExp): string;
 
  //----
  // FORMAT
  //----
  // SPECIAL CHARACTERS
  byte(): string;
  password(): string;
  regex(): string;
  uuid(): string;
 
  // ADDRESSES
  email(): string;
  hostname(): string;
  idnEmail(): string;
  idnHostname(): string;
  iri(): string;
  iriReference(): string;
  ipv4(): string;
  ipv6(): string;
  uri(): string;
  uriReference(): string;
  uriTemplate(): string;
  url(): string;
 
  // TIMESTAMPS
  datetime(minimum?: number, maximum?: number): string;
  date(minimum?: number, maximum?: number): string;
  time(): string;
  duration(): string;
 
  // POINTERS
  jsonPointer(): string;
  relativeJsonPointer(): string;
 
  customs?: IRandomGenerator.CustomMap;
}
export namespace IRandomGenerator {
  export type CustomMap = {
    [Type in keyof Customizable]?: (
      tags: ITypeTag[],
    ) => Customizable[Type] | undefined;
  };
 
  export interface ITypeTag {
    name: string;
    kind: string;
    value: any;
  }
}

You can add custom type tags for random data generation.

As above IRandomGenerator.CustomMap has a little bit complicate type, it may hard to understand for newcomers. However, such newcomers may easily understand, how to customize the random generation, just by reading the following example.

Just define custom type tags like below, then everything would be done.

For reference, when defining custom type tag, typia enforces user to define validate function literal for type safety. Never forget it when you define custom type tags for random generation. Such validation logic definition may enhance your random data generator logic when combining with typia.assert<T>() function.

examples/src/random-customization.ts
import typia from "typia";
import { RandomGenerator } from "typia/lib/utils/RandomGenerator";
 
const data: TagCustom = typia.random<TagCustom>({
  customs: {
    string: (tags) => {
      if (tags.find((t) => t.kind === "dollar") !== undefined)
        return "$" + RandomGenerator.integer();
      const postfix = tags.find((t) => t.kind === "postfix");
      if (postfix !== undefined)
        return RandomGenerator.string() + postfix.value;
    },
  },
});
 
console.log(data);
 
interface TagCustom {
  id: string & typia.tags.Format<"uuid">;
  dollar: string & Dolloar;
  postfix: string & Postfix<"abcd">;
  powerOf: number & PowerOf<2>;
}
 
type Dolloar = typia.tags.TagBase<{
  kind: "dollar";
  target: "string";
  value: undefined;
  validate: `$input[0] === "$" && !isNaN(Number($input.substring(1).split(",").join("")))`;
}>;
 
type Postfix<Value extends string> = typia.tags.TagBase<{
  kind: "postfix";
  target: "string";
  value: Value;
  validate: `$input.endsWith("${Value}")`;
}>;
 
type PowerOf<Value extends number> = typia.tags.TagBase<{
  kind: "powerOf";
  target: "number";
  value: Value;
  validate: `(() => {
        const denominator: number = Math.log(${Value});
        const value: number = Math.log($input) / denominator;
        return Math.abs(value - Math.round(value)) < 0.00000001;
    })()`;
}>;