Skip to Content
📖 Guide DocumentsRandom Generator

typia.random — make up a value that satisfies the type

signatures
function random<T>(generator?: Partial<IRandomGenerator>): Resolved<T>; function createRandom<T>(generator?: Partial<IRandomGenerator>): () => Resolved<T>;

typia.random<T> returns a value that satisfies T. Use it for test fixtures, seeding databases, or building demos without writing factory functions by hand.

It honors satisfiable type tags you put on the type: tags.Format<"email"> will produce an email, tags.Minimum<0> & tags.Maximum<100> will pick a number in that range, tags.MaxLength<8> will cap a string’s length.

Without length tags, plain strings use length 5..10, and non-recursive arrays use length 1..6. Explicit constraints still win: tags.MaxLength<0> can produce "", and tags.MaxItems<0> produces an empty array. Recursive arrays receive recursive: true on the array generator props and use length 0..2 by default so graph-shaped data can terminate. A direct recursive array alias or owner edge, and any array that must serve as the recursive depth cutoff, cannot also require a positive minimum length; typia.random rejects that combination at compile time because the cutoff may need to emit an empty array.

Recursion terminates only where the depth cutoff has an escape to take: an array, set, or map that may be empty, a tuple rest (...T[]) that spreads zero elements, a nullable edge that may become null, an optional or index-signature property that may be dropped, or a union with at least one finite variant. A recursive type whose every cycle is a required, non-nullable, non-container value — interface INode { next: INode } or a mutual A → B → A object cycle — has no finite value to generate, so typia.random rejects it at compile time instead of overflowing the stack. Give the cycle any one escape (next: INode | null, next?: INode, or next: INode[]) to make it satisfiable.

First example

hello-random.ts
import typia, { tags } from "typia"; interface User { id: string & tags.Format<"uuid">; email: string & tags.Format<"email">; age: number & tags.Type<"uint32"> & tags.Minimum<19> & tags.Maximum<99>; hobbies: string[]; } const user = typia.random<User>(); // e.g. // { // id: "b6e0…", // email: "abc@example.com", // age: 47, // hobbies: ["wzPwLvO", "u_a-mqQ"], // }
examples/src/random/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>; }

undefined

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

Reusable factory

const randomUser = typia.createRandom<User>(); const a = randomUser(); const b = randomUser(); // Pass a custom generator at factory creation: const customRandomUser = typia.createRandom<User>(customGenerator); const c = customRandomUser();

The factory takes the generator once at creation and returns a zero-argument function. (If you need different generators per call, just create more factories — they’re cheap.)

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

Tags in action

The constraints you’d normally use for runtime validation also pin down what random produces. Type tags and comment tags compile to the same code, so either style works:

examples/src/random/random-tag.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; }

Type tags are the recommended form. They are statically checked by the TypeScript compiler (a misspelled format string is rejected at compile time), they compose with & and | like any other type, and they let you define custom constraints. Comment tags only exist for legacy JSDoc-style projects, and a typo there falls back to defaults silently — for long-running test suites and especially anything that seeds a real database, prefer type tags. See Special Tags for the trade-off in full.

Custom tags

Defining a custom type tag for validation also gives you a hook for random generation. When you write validate on the tag, typia uses it for assert/is/validate — and uses the tag’s kind to look up a generator on the runtime IRandomGenerator.

examples/src/random/random-custom.ts
import typia from "typia"; import { _randomNumber } from "typia/lib/internal/_randomNumber"; import { _randomString } from "typia/lib/internal/_randomString"; const data: TagCustom = typia.random<TagCustom>({ string: (schema) => { if ((schema as any)["x-typia-monetary"] === "dollar") return "$" + Math.floor(Math.random() * 1_000); else if ((schema as any)["x-typia-postfix"] !== undefined) return _randomString(schema) + (schema as any)["x-typia-postfix"]; return _randomString(schema); }, number: (schema) => { if ((schema as any)["x-typia-powerOf"] !== undefined) { const powerOf = (schema as any)["x-typia-powerOf"]; return Math.pow(powerOf, Math.floor(Math.random() * 10) + 1); } return _randomNumber(schema); }, }); console.log(data); interface TagCustom { id: string & typia.tags.Format<"uuid">; dollar: string & Dollar; postfix: string & Postfix<"abcd">; powerOf: number & PowerOf<2>; } type Dollar = typia.tags.TagBase<{ kind: "monetary"; target: "string"; value: "dollar"; validate: `$input[0] === "$" && !isNaN(Number($input.substring(1).split(",").join("")))`; schema: { "x-typia-monetary": "dollar"; }; }>; type Postfix<Value extends string> = typia.tags.TagBase<{ kind: "postfix"; target: "string"; value: Value; validate: `$input.endsWith("${Value}")`; schema: { "x-typia-postfix": 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; })()`; schema: { "x-typia-powerOf": Value; }; }>;

A custom tag without a validate is fine for documentation purposes, but if you want random to actually produce values that satisfy it, define the validation logic. The same validate then doubles as the check used by typia.assert<T>.

Where to go next

Last updated on