This content originally appeared on DEV Community 👩‍💻👨‍💻 and was authored by Jeongho Nam
Summary
import typia from "typia";
const article: IBbsArticle = typia.random<IBbsArticle>();
I made an universal random generator function, which requires only one line of code.
Just put your type on random<T>()
function of typia, then everything would be done.
Principles
The secret is on category of typia, a transformer library performing AOT compilation.
typia analyzes your TypeScript code, and generates optimal code for the type T
, in the compilation level. Such code generation, in the compilation level, for optimization is called "AOT (Ahead of Time) compilation". The random<T>()
is one of transformer function, supported by typia.
To understand what transformation and AOT compliation are, just read below code:
IBbsArticle.ts
interface IBbsArticle {
/**
* @format uuid
*/
id: string;
writer: IBbsArticle.IWriter;
/**
* @minItems 1
* @maxItems 10
*/
snapshots: IBbsArticle.ISnapshot[];
}
namespace IBbsArticle {
export interface IWriter {
/**
* @pattern ^[a-zA-Z0-9]{3,20}$
*/
name: string | null;
/**
* @format email
*/
email: string;
}
export interface ISnapshot {
/**
* @format uuid
*/
id: string;
/**
* @minLength 5
* @maxLength 100
*/
title: string;
body: string;
}
}
Compiled JavaScript Code
import typia from "typia";
const article = ((generator = typia.random.generator) => {
const $generator = typia.random.generator;
const $pick = typia.random.pick;
const $ro0 = (recursive = false, depth = 0) => ({
id: (generator.uuid ?? $generator.uuid)(),
writer: $ro1(recursive, recursive ? 1 + depth : depth),
snapshots: generator.array(
() => $ro2(recursive, recursive ? 1 + depth : depth),
generator.integer(1, 3),
),
});
const $ro1 = (recursive = false, depth = 0) => ({
name: $pick([
() => null,
() =>
(generator.pattern ?? $generator.pattern)(
/^[a-zA-Z0-9]{3,20}$/,
),
])(),
email: (generator.email ?? $generator.email)(),
});
const $ro2 = (recursive = false, depth = 0) => ({
id: (generator.uuid ?? $generator.uuid)(),
title: generator.string(generator.integer(5, 100)),
body: generator.string(),
});
return $ro0();
})();
Comment Tags
You may found that there had been some speical comments in the IBbsArticle
type.
It is called comment tags and they're used to specifying what to generate.
Below is a list comment tags supported by typia. With these comment tags, you can enhance random data generation. Also, if you have a good idea which can specialize how to generate random data, please let me know by writing an issue on typia.
Tag Kind | Target Type |
---|---|
`@type {"int"\ | "uint"}` |
@minimum {number} |
number |
@maximum {number} |
number |
@exclusiveMinimum {number} |
number |
@exclusiveMaximum {number} |
number |
@multipleOf {number} |
number |
@step {number} |
number |
@length {number} |
string |
@minLength {number} |
string |
@maxLength {number} |
string |
`@format {"email"\ | "uuid"\ |
{% raw %}@pattern {string}
|
string |
@items {number} |
array |
@minItems {number} |
array |
@maxItems {number} |
array |
export interface TagExample {
/* -----------------------------------------------------------
ARRAYS
----------------------------------------------------------- */
/**
* You can limit array length like below.
*
* @minItems 3
* @maxItems 10
*
* Also, you can use `@items` tag to fix length.
*
* @items 5
*
* Furthermore, you can use additional tags for each item.
*
* @type uint
* @format uuid
*/
array: Array<string|number>;
/**
* If two-dimensional array comes, length limit would work for
* both 1st and 2nd level arrays. Also using additional tags
* for each item (string) would still work.
*
* @minItems 5
* @maxItems 10
* @format url
*/
matrix: string[][];
/* -----------------------------------------------------------
NUMBERS
----------------------------------------------------------- */
/**
* Type of number.
*
* It must be one of integer or unsigned integer.
*
* @type int
* @type uint
*/
type: number;
/**
* You can limit range of numeric value like below.
*
* @minimum 5
* @maximum 10
*
* Also, you can use exclusive tags instead
*
* @exclusiveMinimum 4
* @exclusiveMaximum 11
*/
range: number;
/**
* Step tag requires minimum or exclusiveMinimum tag.
*
* 3, 13, 23, 33, ...
*
* @step 10
* @exclusiveMinimum 3
*/
step: number;
/**
* Value must be multiple of the given number.
*
* -5, 0, 5, 10, 15, ...
*
* @multipleOf 5
*/
multipleOf: number;
/* -----------------------------------------------------------
STRINGS
----------------------------------------------------------- */
/**
* You can limit string length like below.
*
* @minLength 3
* @maxLength 10
*
* Also, you can use `@length` tag to fix length.
*
* @length 7
*/
length: string;
/**
* Mobile number composed by only numbers.
*
* Note that, `typia` does not support flag of regex,
* because JSON schema definition does not support it either.
* Therefore, write regex pattern without `/` characters and flag.
*
* @pattern ^0[0-9]{7,16}
* -> RegExp(/[0-9]{7,16}/).test("01012345678")
*/
mobile: string;
/**
* E-mail address.
*
* @format email
*/
email: string;
/**
* UUID value.
*
* @format uuid
*/
uuid: string;
/**
* URL address.
*
* @format url
*/
url: string;
/**
* IPv4 address.
*
* @format ipv4
*/
ipv4: string;
/**
* IPv6 address.
*
* @format ipv6
*/
ipv6: string;
}
More Functions
// RUNTIME VALIDATORS
export function is<T>(input: unknown | T): input is T; // returns boolean
export function assert<T>(input: unknown | T): T; // throws TypeGuardError
export function validate<T>(input: unknown | T): IValidation<T>; // detailed
// JSON
export function application<T>(): IJsonApplication; // JSON schema
export function assertParse<T>(input: string): T; // type safe parser
export function assertStringify<T>(input: T): string; // safe and faster
// +) isParse, validateParse
// +) stringify, isStringify, validateStringify
// MISC
export function random<T>(): Primitive<T>; // generate random data
export function clone<T>(input: T): Primitive<T>;
export function prune<T extends object>(input: T): void;
// +) isClone, assertClone, validateClone
// +) isPrune, assertPrune, validatePrune
typia supports more transformer functions like above.
All of those function can be performed only one line. When you use any function of them, typia will generate optimal code instead of you, by analyzing your TypeScript code in the compilation level.
Furthermore, such convenient transformer functions are superfast. Comparing validation speed with other library class-validator
, typia is maximum 15,000x faster than class-validator
. Otherwise, comparing stringify()
function, typia is 10x faster thhan native JSON.stringify()
function and even type safe.
- [Typia] 15,000x faster TypeScript Validator and its histories
- I made 10x faster
JSON.stringify()
functions, even type safe
This content originally appeared on DEV Community 👩‍💻👨‍💻 and was authored by Jeongho Nam
Jeongho Nam | Sciencx (2023-02-15T18:34:32+00:00) [Typia] Universal Random Generator, which can make everything, just by only one line. Retrieved from https://www.scien.cx/2023/02/15/typia-universal-random-generator-which-can-make-everything-just-by-only-one-line/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.