
This story is about a precursor library typescript-is:
typia named typescript-is
zod and class-validatortypescript-json
typescript-isnestia by combining both of them
NestJS helper librarytypescript-istypescript-jsontypescript-is has stopped maintenance since two years agotypescript-json to cover typescript-is features
typescript-istypiatypescript-is author to uphold typia
typescript-is agreedtypescript-is is unified with typia, formallytypescript-is, and say good byeRelated Repositories:
typescript-isexport function is<T>(input: unknown): input is T;
export function assertType<T>(input: unknown): T;
export function validate<T>(input: unknown): ValidationResult<T>;import { is } from "typescript-is";
is<number>(3);import { is } from "typescript-is";
((input) => {
if (typeof input !== "number")
return false;
return true;
})(3);This is the AoT compilation.
typescript-isanalyzes the TypeScript source codes, and transforms to optimal JavaScript codes, for the target typeT(number).
https://github.com/woutervh-/typescript-isΒ
Long time ago, there had been a great validator library named typescript-is.
It had performed AoT (Ahead of Time) compilation through TypeScript Compiler API. As it requires only one line with pure TypeScript type like above, it was much convenient than any other validator libraries like zod or class-validator.
In my case, Iβd developed backend server through NestJS framework. By the way, the NestJS developer recommends to using class-validator, one of the most horrible library than what Iβve ever experienced. It enforces user to define quadruple duplicated structure, and extremely slow validation speed is extremely slow (6MB/s). It even has enormous bugs that saying βthereβs no problemβ for wrong data, and maintainer seems to be not interested in fixing those bugs.
// CLASS-VALIDATOR REQUIRES DUPLICATED DEFINITIONS
export class BbsArticle {
@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;
}
// TYPESCRIPT-IS OKAY WITH PURE TYPESCRIPT TYPE
export interface IBbsArticle {
/**
* List of attached files.
*/
files: IAttachmentFile[] | null;
}class-validator tests only 16 casestypescript-is tests about 100 casestypia tests 10K cases with 1M LOC codesInstead, Iβd loved to using typescript-is in NestJS projects. It was much convenient and safer than class-validator. Only one line was required, and need not to be suffered from enormous bugs (typescript-is also could not validate union or complicate types either, but not as serious as class-validator).
Using typescript-is for the NestJS backend projects, Iβd admired the genius idea of typescript-is author, and always thankful that it frees me from the nightmare of class-validator.
If you feel like youβve heard this story somewhere, youβre right.
typescript-isis an ancestor library oftypia, and is a project that implemented a validator based on AOT compilation beforetypia.However, maintenance had been stopped and broken since 2 years ago.
In recent years, cataclysms came to the TypeScript language several times, and typescript-is, which had been built on the TypeScript Compiler API, broke frequently. However, its author could not maintain the project due to being busy, so typescript-is had effectively been broken for about two years while I waited for his return.
typescript-json// JSON SCHEMA GENERATOR
export function application<
Types extends unknown[],
Purpose extends "swagger"|"ajv"
>(): IJsonSchema;
// JSON SERIALIZATION BOOSTER
export function stringify<T>(input: T): string;Around the same time, I had made another library named typescript-json.
It performs AoT (Ahead of Time) compilation like typescript-is, but it was not for runtime validation, but for JSON schema generation. About JSON serialization boosting, typescript-json had utilized fast-json-stringify by automatically generated JSON schema.
For reference, purpose of typescript-json was to accomplish below nestia, generating Swagger Documents with pure TypeScript type.
nestia
https://github.com/samchon/typiaΒ
Using typescript-is in NestJS made backend developments were much easier and convenient.
However, in that case, it was not possible to generate Swagger Documents. Itβs because swagger generator of NestJS could not analyze TypeScript source code in the compilation level. Instead, it required quadruple duplicated definitions through decorator function calls.
At that time, Iβd thought it would better to make an alternative swagger generator for NestJS project. Although it needs complicated logics like analyzing NestJS utilization TypeScript source codes in the compilation level, I thought that it is much worthy work instead of rolling back to the terrible class-validator. I wanted to progress rather than regress.
Therefore, Iβd made a new library named nestia. It had performed validation through typescript-is, and had generated Swagger Documents through typescript-json. Also, after succeeded to anayzing NestJS source codes, I made more features like SDK (Software Development Kit) library generator like below.
My team members (especially frontend developers) were very happy with it, and looking at them, Iβd thought that βI did a right decisionβ. As a result of avoiding class-validator, which I really donβt want to use, and pursuing beautiful typescript-is, efficiency has more than doubled even including frontend developers.

Left is
NestJSserver code, and right is client (frontend) code utilizing SDK.In nowadays,
nestiacan generate Mock Simulator, and even possible to build those SDK library and Mockup Simulator through aswagger.jsonfile. It means that, you can build SDK library and Mockup Simulator from every languages and frameworks.
- SDK: a collection of
fetchfunctions with type definitions- Mockup simulator: embedded backend simulator in SDK
typescript-istypescript-is author has stopped maintenance, and it was a critical problem for nestia.
The moment when cheered for the right choice and had fun with my teammates, typescript-is has been died suddenly. In actually, typescript-is was already out of maintenance even before starting nestia development. Unfortunately, at that moment, TypeScript had been break changed a lot in compiler API for several times, and typescript-is had been broken since 2 years ago.
It was very embarrassing that typescript-is suddenly died not long after making nestia and tasting its fruits. At that time, I thought for a while that should I turn back to the terrible and hopeless class-validator or not. Developing nestia, I had consumed about an year, and the one year is not a short time. Therefore, I considered it for a while.
However, my final decision was still same with before: βLetβs make one thing more, and one year more. Rather than using that horrible class-validator again, it makes sense to spend another year again, and it would be a great opportunity for studying to me.β
typia// RUNTIME VALIDATORS
export function is<T>(input: unknown): input is T; // returns boolean
export function assert<T>(input: unknown): T; // throws TypeGuardError
export function validate<T>(input: unknown): IValidation<T>; // detailed
export const customValidators: CustomValidatorMap; // for customization
// JSON FUNCTIONS
export namespace 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
}
// PROTOCOL BUFFER (NOT YET, BUT SOON)
export namespace protobuf {
export function message<T>(): string; // Protocol Buffer message
export function assertDecode<T>(buffer: Buffer): T; // safe decoder
export function assertEncode<T>(input: T): Uint8Array; // safe encoder
}
// RANDOM GENERATOR
export function random<T>(g?: Partial<IRandomGenerator>): T;https://github.com/samchon/typiaΒ
Evolved typescript-json to cover typescript-is features, and renamed to typia.
As typescript-is had stopped maintenance and broken by update of TypeScript compiler, and it was a critical problem for my project nestia, Iβd decided to enhance typescript-json to cover typescript-is features. Also, Iβd renamed typescript-json to typia, because that library is no more designed only for JSON related functions.
Also, as typescript-json had designed to generate JSON schema from TypeScript types, it must have well-designed metadata definition for TypeScript types. Besides, typescript-is had not designed metadata structure, and just wrote a lot of hard coded if statements for TypeScript types. Such different made typia to have much more LOC (Line of Codes) than typescript-is, but typia could be much stable than before typescript-is.
Furthermore, Iβve enhanced typia through 1,000,000 LOC test codes. Considering characteristics of typia using pure TypeScript type, typia must support every TypeScript type cases. Also, expression power of TypeScript about type is the much more powerful and wider than any other languages. Therefore, to support every TypeScript types safely, I had to write enormous test codes about one million LOC. It was a hard work for me during one year, but such endurance evolved typia to be only one validator library which supports every TypeScript types.
typia tests 10K cases with 1M LOC codestypescript-is tests about 100 casesclass-validator tests only 16 cases| Components | typia | ts-is | typebox | ajv | io-ts | zod | c.v. |
|---|---|---|---|---|---|---|---|
| Easy to use | β | β | β | β | β | β | β |
| Object (simple)Β | β | β | β | β | β | β | β |
| Object (hierarchical)Β | β | β | β | β | β | β | β |
| Object (recursive)Β | β | β | β | β | β | β | β |
| Object (union, implicit)Β | β | β | β | β | β | β | β |
| Object (union, explicit)Β | β | β | β | β | β | β | β |
| Object (additional tags)Β | β | β | β | β | β | β | β |
| Object (template literal types)Β | β | β | β | β | β | β | β |
| Object (dynamic properties)Β | β | β | β | β | β | β | β |
| Array (rest tuple)Β | β | β | β | β | β | β | β |
| Array (hierarchical)Β | β | β | β | β | β | β | β |
| Array (recursive)Β | β | β | β | β | β | β | β |
| Array (recursive, union)Β | β | β | β | β | β | β | β |
| Array (R+U, implicit)Β | β | β | β | β | β | β | β |
| Array (repeated)Β | β | β | β | β | β | β | β |
| Array (repeated, union)Β | β | β | β | β | β | β | β |
| Ultimate Union Type | β | β | β | β | β | β | β |
Data structure of
typiafor TypeScript types:For reference, as
typescript-isdoesnβt have such well-structured metadata definition, and it is the reason whytypescript-iscannot validate complicate type. However, to make an excuse fortypescript-is, it was the most stable of the validator libraries at that time, and even still much more stable than the terribleclass-validator.
ts-ismeanstypescript-isc.v.meansclass-validator
Also, as typia performs AoT (Ahead of Time) compilation skill, and nestia is utilizing such typia features, I could enhance NestJS performance enormously. Current nestia can enhance NestJS server performance like below:
class-validatorclass-transformerNestJS server performance be 30x uptypescript-ishttps://github.com/woutervh-/typescript-is/issues/137Β
A year has passed since the successful development of typia. And in the meantime, typescript-is is still out of maintenance. Therefore, Iβve written an issue to typescript-is repo requesting deprecate typescript-is and uphold typia instead.
While writing the issue, I also left a message of appreciation for typescript-isβs pioneering ideas, and past dedications that helped me to escape from terrible class-validator. Thanks for his great idea, and I could learn lots of things by motivated from his project.
At past week, typescript-is author accepted my suggestion and typescript-is has started upholding typia. From now on, typescript-is is unified with typia, formally. Thanks for pioneering challenge of typescript-is, and say good bye.
Recently, Iβve written some articles about AoT compilation.
By the way, Iβve only told you that AoT compilation is much faster than dynamic key accessing logics, but have not explained from a theoretical point of view. The next article would be about that.
Letβs study the reason why AoT compilation makes your code faster.
I dislike class-validator due to bad experience.
When developing a NestJS backend server about insurance service, Iβd used class-validator, but suffered from its extremely slow performance. class-validator can validate only 6MB data per a second, and unfortunately, each contract of insurance easily exceeds 3MB. At that time, my backend server can get only 4 connections per a second, and it was a critical problem for business.
It was the reason why I abandoned class-validator and used typescript-is instead. And as you could see from here article, such bad experience made me to develop typia and nestia. The next article would be about this story.
If you can read Korean language, you can read the story from here right, now. If not, wait my next article please.