Pure TypeScript
Outline
typia.assert<IBbsArticle>(article);
typia
needs only one line with pure TypeScript type.
You know what? Every other validator libraries need extra schema definition, that is different with pure TypeScript type. For an example, class-validator
is the most famous validator due to used in NestJS
. However, NestJS
and class-validator
force you to define triple duplicated DTO schema.
- TypeScript Type
class-validator
decorators@nestjs/swagger
decorators
Another famous validator library ajv
requires JSON schema definition. Move to the #Demonstration, and click the ajv (JSON Schema)
tab, then you may understand how it terrible. It requires hundreds of lines of JSON schema definition even just for a simple DTO.
Those duplicated schema definitions are not only annoying, but also error-prone. If you take any mistake on the extra schema definition, such mistake can’t be detected by TypeScript compiler. It will be detected only at runtime, therefore become a critical runtime error. Another words, it is not type safe.
Besides, typia
only needs pure TypeScript type. You don’t need to define any extra schema like class-validator
or ajv
. Just define pure TypeScript type only (especially recommend to use interface
type), then typia
will do all the rest.
Demonstration
If you’re confusing how typia
is different with others, just see example codes below.
At first, look at the first (class-validator
) tab, and find the BbsArticle.files
property, enhanced by blue coloured blocks. Looking at the files
property, how do you feel? Just defining an array object type, you’ve to call 7 decorator functions. If you take any mistake when using the decorator like omitting isArray
property, it would be a critical runtime erorr.
Besides, typia
needs only one line. Click the third (typia
) tab, and find the IAttachmentFile.files
property. Only one line being used, and they are even not class, but just interface types. Comparing it to the first and second tabs, how do you feel? Isn’t it more simple and readable?
This is the power of typia
, with pure TypeScript type.
import { ApiProperty } from "@nestjs/swagger";
import {
ArrayNotEmpty,
IsArray,
IsObject,
IsOptional,
IsString,
Match,
MaxLength,
Type,
ValidateNested,
} from "class-validator";
export class BbsArticle {
@ApiProperty({
format: "uuid",
})
@IsString()
id!: string;
// DUPLICATED SCHEMA DEFINITION
// - duplicated function call + property type
// - have to specify `isArray` and `nullable` props by yourself
@ApiProperty({
type: () => AttachmentFile,
nullable: true,
isArray: true,
description: "List of attached files.",
})
@Type(() => AttachmentFile)
@IsArray()
@IsOptional()
@IsObject({ each: true })
@ValidateNested({ each: true })
files!: AttachmentFile[] | null;
@ApiProperty({
type: "string",
nullable: true,
minLength: 5,
maxLength: 100,
description: "Title of the article.",
})
@IsOptional()
@IsString()
title!: string | null;
@ApiProperty({
description: "Main content body of the article.",
})
@IsString()
body!: string;
@ApiProperty({
format: "date-time",
description: "Creation time of article",
})
@IsString()
created_at!: string;
}
export class AttachmentFile {
@ApiProperty({
type: "string",
maxLength: 255,
pattern: "^[a-zA-Z0-9-_]+$",
description: "File name.",
})
@Matches(/^[a-z0-9]+$/)
@MaxLength(255)
@IsString()
name!: string | null;
@ApiProperty({
type: "string",
nullable: true,
maxLength: 255,
pattern: "^[a-zA-Z0-9-_]+$",
description: "File extension.",
})
@Matches(/^[a-z0-9]+$/)
@MaxLength(8)
@IsOptional()
@IsString()
extension!: string | null;
@ApiProperty({
format: "url",
description: "URL of the file.",
})
@IsString()
url!: string;
}
AOT Compilation
Someone may be suspicious of the phrase “Pure TypeScript Type”.
“As you know, TypeScript types do not have any tangible instance when compiled to JS.
However, with only these fictitious TypeScript types, how can
typia
validates types at runtime? Howtypia
builds much faster JSON serializer only with these types? Are these things really possible without extra schema definition likeclass-validator
orajv
?”
My answer is: “Yes, it is possible due to typia
analyzes your server code, and performs AOT compilation”.
Such compile time optimization is called AOT (Ahead of Time) compilation. And this is the secret why typia
can do everything with only pure TypeScript type. Read below example codes, and just look how JavaScript file being compiled. Then you may understand why typia
is much easier, and futhermore much faster.
- Runtime validator is 20,000x faster than
class-validator
- JSON serialization is 200x faster than
class-transformer
import typia from "typia";
import { IBbsArticle } from "./IBbsArticle";
export const assertArticle = typia.createAssert<IBbsArticle>();
Measured on AMD Ryzen 9 7940HS, Rog Flow x13