Summary
This story is about a precursor library typescript-is
:
- There had been an ancesor library of
typia
namedtypescript-is
- Only one line required
- AoT (Ahead of Time) compilation through TypeScript Compiler API
- Much convenient than any other validator libraries like
zod
andclass-validator
- I had another library
typescript-json
- Boost up JSON serialization speed
- JSON schema generation
- Performs AOT compilation like
typescript-is
- I had developed
nestia
by combining both of them-
NestJS
helper library - Validators by
typescript-is
- JSON booster and Swagger generation by
typescript-json
-
-
typescript-is
has stopped maintanence since two years ago - I've changed
typescript-json
to covertypescript-is
features- Added validator features like
typescript-is
- Enhanced by 1M LOC test codes
- Renamed to
typia
- Added validator features like
- Today, I requested
typescript-is
author to upholdtypia
- Author of
typescript-is
agreed - From now on,
typescript-is
is unified withtypia
, formally
- Author of
- Thanks for pioneering challenge of
typescript-is
, and say good bye
Related Repositories:
- typescript-is: https://github.com/woutervh-/typescript-is
- typia: https://github.com/samchon/typia
- nestia: https://github.com/samchon/nestia
- Good bye issue: https://github.com/woutervh-/typescript-is/issues/137
typescript-is
Features
export function is<T>(input: unknown): input is T;
export function assertType<T>(input: unknown): T;
export function validate<T>(input: unknown): ValidationResult<T>;
TypeScript Source File
import { is } from "typescript-is";
is<number>(3);
Compiled JavaScript File
import { is } from "typescript-is";
((input) => {
if (typeof input !== "number")
return false;
return true;
})(3);
This is the AoT compilation.
typescript-is
analyzes 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 REQUIES DUPLCIATED 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 cases -
typescript-is
tests about 100 cases -
typia
tests 10K cases with 1M LOC codes
Instead, 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 enourmous 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-is
is 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.
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) compliation 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
NestJS
server code, and right is client (frontend) code utilizing SDK.In nowadays,
nestia
can generate Mock Simulator, and even possible to build those SDK library and Mockup Simulator through aswagger.json
file. It means that, you can build SDK library and Mockup Simulator from every languages and frameworks.
- SDK: a collection of
fetch
functions with type definitions- Mockup simulator: embedded backend simulator in SDK
Death of typescript-is
typescript-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 libary which supports every TypeScript types.
-
typia
tests 10K cases with 1M LOC codes -
typescript-is
tests about 100 cases -
class-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
typia
for TypeScript types:For reference, as
typescript-is
doesn't have such well-structured metadata definition, and it is the reason whytypescript-is
cannot 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-validato
r.
ts-is
meanstypescript-is
c.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:
- 20,000x faster validation speed than
class-validator
- 200x faster JSON serialization speed than
class-transformer
- Composite
NestJS
server performance be 30x up - Benchmark Results
Good bye typescript-is
https://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 derepcate 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.
Next Story
Theoretical Explanation
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.
Behind Story of Nestia
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.
Top comments (5)
Any tests with ajv?
Do you know fastify js?
I know
fastify
and also testedajv
.What do you want to ask me?
Speed for them is very important!
Could you contribute if you can
hugs
github.com/samchon/schedules#fasti...
Planning to make plugin library, and it will be possible to generate like nestia. By the way, as I'm developing open source libaries only when leisure time, I cannot sure it would be completed in 2023-9.
What a nice work.