MockData
MockData<T> gives a type realistic sample values: pools of believable names and emails, ranges for numbers and dates, and a few hints for arrays and optional fields. It feeds the createMockType<T>() generator. The AI supplies the believable values, and the generator handles the rest. Like FriendlyType<T>, you commit it next to your type and the compiler checks it against that type on every build.
How it's shaped
The map mirrors your type. Each field carries the knobs that make sense for its kind. The compiler scaffolds an entry for every field with the blanks marked @todo, then the agent fills in believable values.
import type * as TF from 'ts-runtypes/formats';
// models/user.ts
export interface User {
name: TF.String<{ minLength: 2; maxLength: 60 }>;
age: TF.Number<{ min: 0; max: 120 }>;
isActive: boolean;
tags: string[];
profile: {
email: TF.Email;
score: TF.Number<{ min: 0; max: 100 }>;
};
}
import type { MockData } from 'ts-runtypes';
import type { User } from './user';
// scaffolded by `gen`: one entry per field, each blank marked @todo
export const userMock: MockData<User> = {
name: { pool: [] }, // @todo believable names
age: { min: 0, max: 0 }, // @todo realistic range
isActive: { pool: [] }, // @todo
tags: { $items: { pool: [] }, $length: [0, 0] }, // @todo
profile: {
email: { pool: [] }, // @todo real-looking addresses
score: { min: 0, max: 0 }, // @todo realistic range
},
};
import type { MockData } from 'ts-runtypes';
import type { User } from './user';
export const userMock: MockData<User> = {
name: { pool: ['Alice Martin', 'Liang Wei', 'Fatima Noor', /* …50+ */] },
age: { min: 18, max: 95 },
isActive: { pool: [true, true, false] },
tags: { $items: { pool: ['urgent', 'beta', 'vip'] }, $length: [1, 4] },
profile: {
email: { pool: ['alice@example.com', 'liang@corp.io', /* … */] },
score: { min: 0, max: 100 },
},
};
The per-field knobs, by kind:
| Knob | Applies to | What it does |
|---|---|---|
pool | strings, numbers, booleans, bigints, … | draw the value from this list |
min / max | numbers, dates | bound the generated range |
$items | arrays, tuples | the element node (a MockData node for T[number]) |
$length | arrays | fixed length, or a [min, max] range |
$optional | objects | present-probability (0 to 1) for optional members |
Then feed it to the generator through the data option:
import { createMockType } from 'ts-runtypes';
import { userMock } from 'runtypes/generated/models/user';
const mockUser = createMockType<User>({ data: userMock });
mockUser();
// → { name: 'Liang Wei', age: 41, isActive: true,
// tags: ['beta', 'vip'],
// profile: { email: 'liang@corp.io', score: 73 } }
data option is purely additive. Leave it out and the generator works exactly as it does today. The MockData<T> type and the createMockType({ data }) integration ship today; the build-time check on pool values is still in development.Every sample value is checked
Because RunTypes already knows how to validate, the compiler checks that every value in your pools and ranges is actually valid for its field, at build time and not when your tests run. If an AI drops a malformed address into the email pool, or a score of 150, the build catches it:
export const userMock: MockData<User> = {
profile: {
email: { pool: ['alice@example.com', 'not-an-email'] }, // error: 'not-an-email' isn't a valid email
score: { min: 0, max: 150 }, // error: 150 is above the field's max of 100
},
};
No other mock library does this; it falls straight out of the validator RunTypes already has. (Mistakes like min above max get flagged too.)
Format-aware by default
Even without a pool, the generator already respects type formats: an email field gets a real-looking address, a uuidv4 field a real-looking UUID. MockData<T> is for when mechanical-but-valid isn't enough and you want believable: real names in name, your own domains in email, realistic ranges in age. Anything you don't pin falls back to the format-aware mechanical generator.
MockData<T> in tests and seed scripts (the same place createMockType already lives) and normal tree-shaking keeps it out of your shipped code.