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 createMockDataFn<T>() generator. The AI supplies the believable values, and the generator handles the rest. Like FriendlyText<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/core/formats';
// models/user.ts — the source type every enrichment example derives from.
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/core';
import type {User} from './user';
// scaffolded by `gen`: one entry per field, each blank marked @todo
export const mockUser: MockData<User> = {
name: {pool: []}, // @todo believable names
age: {pool: []}, // @todo realistic range (or min/max bounds)
isActive: {pool: []}, // @todo
tags: {rt$items: {pool: []}, rt$length: [0, 0]}, // @todo
profile: {
email: {pool: []}, // @todo real-looking addresses
score: {pool: []}, // @todo realistic range (or min/max bounds)
},
};
import type {MockData} from '@ts-runtypes/core';
import type {User} from './user';
export const mockUser: MockData<User> = {
name: {pool: ['Alice Martin', 'Liang Wei', 'Fatima Noor' /* …50+ */]},
age: {pool: [], min: 18, max: 95}, // empty pool: draw from the range instead
isActive: {pool: [true, true, false]},
tags: {rt$items: {pool: ['urgent', 'beta', 'vip']}, rt$length: [1, 4]},
profile: {
email: {pool: ['alice@example.com', 'liang@corp.io' /* … */]},
score: {pool: [], 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 |
rt$items | arrays, tuples | the element node (a MockData node for T[number]) |
rt$length | arrays | fixed length, or a [min, max] range |
rt$optional | objects | present-probability (0 to 1) for optional members |
Then feed it to the generator through the data option:
import {createMockDataFn} from '@ts-runtypes/core';
import type {User} from './user';
import {mockUser} from './mock-user';
const newUser = createMockDataFn<User>(undefined, {data: mockUser});
newUser();
// → { 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 createMockDataFn({ 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 mockUser: 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 createMockDataFn already lives) and normal tree-shaking keeps it out of your shipped code.