TypeScript-JSON: 2x faster JSON stringify function with only one line

Last update: Jun 17, 2022

TypeScript-JSON

GitHub license npm version Downloads Build Status

2x faster JSON.stringify() function with only one line.

(input);">
import TSON from "typescript-json";
TSON.stringify<T>(input);

Introduction

typescript-json is a wrapper library of fast-json-stringify, which can generate JSON string 2x faster than the native JSON.stringify() function. Also, typescript-json doesn't need any JSON schema definition. It just requires only one line: TSON.stringify(input).

If you choose other similar libraries like ajv or fast-json-stringify, you've to define a complicated JSON schema that is different from the TypeScript type system. Besides, typescript-json requires only one line with your own TypeScript type definition. You don't need any extra JSON schema definition.

Look at the below code and feel how typescript-json is powerful.

(); stringify(company); // Direct stringify function call // // The type would be stored in the global memory // It would be reused whenever the same type has come TSON.stringify(company); //---- // "fast-json-stringfy" requires complicated JSON schema //---- fast({ type: "object", properties: { name: { type: "string", nullable: false, }, employees: { type: "array", items: { type: "object", properties: { name: { type: "string", nullable: false, }, gender: { oneOf: [ { type: "string" }, { type: "number" } ], nullable: true } } }, nullable: false } } })(company);">
import TSON from "typescript-json";
import fast from "fast-json-stringify";

interface ICompany
{
    name: string;
    employees: IEmployee[];
}
interface IEmployee
{
    name: string;
    gender: string | number | null;
}
const company: ICompany;

//----
// TSON requires only one line
//----
// Reusable stringfy function
const stringify = TSON.createStringifier<ICompany>();
stringify(company);

// Direct stringify function call
// 
// The type would be stored in the global memory
// It would be reused whenever the same type has come
TSON.stringify<ICompany>(company);

//----
// "fast-json-stringfy" requires complicated JSON schema
//----
fast({
    type: "object",
    properties: {
        name: {
            type: "string",
            nullable: false,
        },
        employees: {
            type: "array",
            items: {
                type: "object",
                properties: {
                    name: {
                        type: "string",
                        nullable: false,
                    },
                    gender: {
                        oneOf: [
                            { type: "string" },
                            { type: "number" }
                        ],
                        nullable: true
                    }
                }
            },
            nullable: false
        }
    }
})(company);

Setup

NPM Package

At first, install this typescript-json by the npm install command.

Also, you need additional devDependencies to compile the TypeScript code with transformation. Therefore, install those all libraries typescript, ttypescript and ts-node. Inform that, the ttypescript is not mis-writing. Therefore, do not forget to install the ttypescript.

npm install --save typescript-json

# ENSURE THOSE PACKAGES ARE INSTALLED
npm install --save-dev typescript
npm install --save-dev ttypescript
npm install --save-dev ts-node

tsconfig.json

After the installation, you've to configure the tsconfig.json file like below. Add the new property transform and its value typescript-json/lib/transform into the compilerOptions.plugins array.

{
  "compilerOptions": {
    "plugins": [
      {
        "transform": "typescript-json/lib/transform"
      }
    ]
  }
}

After the tsconfig.json definition, you can compile typescript-json utilized code by using the ttypescript. If you want to run your TypeScript file through the ts-node, use -C ttypescript argument like below:

# COMPILE
npx ttsc

# WITH TS-NODE
npx ts-node -C ttypescript

webpack

If you're using a webpack with the ts-loader, configure the webpack.config.js file like below:

const transform = require('typescript-json/lib/transform').default

module.exports = {
    // I am hiding the rest of the webpack config
    module: {
        rules: [
            {
                test: /\.ts$/,
                exclude: /node_modules/,
                loader: 'ts-loader',
                options: {
                    getCustomTransformers: program => ({
                        before: [transform(program)]
                    })
                }
            }
        ]
    }
};

Features

Functions

export function stringify<T>(input: T): string;
export function createStringifier<T>(): (input: T) => string;
export function createApplication<T>(): (input: T) => IJsonApplication;

typescript-json provides only three functions, stringify(), createStringifier() and createApplication().

The first stringify() is a function who returns the JSON string directly. Also, the type you'd put into the generic argument would be stored in the global memory and reused whenever calling the stringify() function with the same type.

The second createStringifier() is a function who returns another function that can generate the JSON string. The createStringifier() is not enough convenient like stringify(), however it doesn't consume the global memory. Also, the returned function from the createStringifier() is always reusable until you forget the function variable.

The last createApplication() is just a function who generates JSON schema following the type T. If you need to utilize the JSON schema for other purpose, this function would be useful.

Method Strength Weakness
stringify() Convenient to use Use global memory
createStringifier() Save global memory Inconvenient to manage
createApplication() Reusable JSON Schema Surplus feature, maybe?

public

When you put a class type into this typescript-json, only public members would be converted to JSON string. The private or protected members would be all ignored.

toJSON()

fast-json-stringify is not supporting the toJSON() method. If such unsupported situation keeps for a long time, I promise you that I'll fix the problem even by developing the JSON conversion logic by myself.

Appendix

Nestia

My another library using this typescript-json.

https://github.com/samchon/nestia

Automatic SDK and Swagger generator for the NestJS, evolved than ever.

nestia is an evolved SDK and Swagger generator, which analyzes your NestJS server code in the compilation level. With nestia and compilation level analyzer, you don't need to write any swagger or class-validator decorators.

Reading below table and example code, feel how the "compilation level" makes nestia stronger.

Components nestia::SDK nestia::swagger @nestjs/swagger
Pure DTO interface
Description comments
Simple structure
Generic type
Union type
Intersection type
Conditional type
Auto completion
Type hints
2x faster JSON.stringify()
Ensure type safety
{ // LIST UP SALE SUMMARIES const index: IPage = await api.functional.shoppings.sales.index ( connection, "general", { limit: 100, page: 1 } ); // PICK A SALE const sale: ISale = await api.functional.shoppings.sales.at ( connection, index.data[0].id ); console.log("sale", sale); // WRITE A QUESTION const question: ISaleQuestion = await api.functional.shoppings.sales.questions.store ( connection, "general", sale.id, { title: "How to use this product?", body: "The description is not fully enough. Can you introduce me more?", files: [] } ); console.log("question", question); // WRITE A COMMENT const comment: ISaleArticleComment = await api.functional.shoppings.sales.comments.store ( connection, "general", sale.id, question.id, { body: "p.s) Can you send me a detailed catalogue?", anonymous: false } ); console.log("comment", comment); }">
// IMPORT SDK LIBRARY GENERATED BY NESTIA
import api from "@samchon/shopping-api";
import { IPage } from "@samchon/shopping-api/lib/structures/IPage";
import { ISale } from "@samchon/shopping-api/lib/structures/ISale";
import { ISaleArticleComment } from "@samchon/shopping-api/lib/structures/ISaleArticleComment";
import { ISaleQuestion } from "@samchon/shopping-api/lib/structures/ISaleQuestion";

export async function trace_sale_question_and_comment
    (connection: api.IConnection): Promise<void>
{
    // LIST UP SALE SUMMARIES
    const index: IPage<ISale.ISummary> = await api.functional.shoppings.sales.index
    (
        connection,
        "general",
        { limit: 100, page: 1 }
    );

    // PICK A SALE
    const sale: ISale = await api.functional.shoppings.sales.at
    (
        connection, 
        index.data[0].id
    );
    console.log("sale", sale);

    // WRITE A QUESTION
    const question: ISaleQuestion = await api.functional.shoppings.sales.questions.store
    (
        connection,
        "general",
        sale.id,
        {
            title: "How to use this product?",
            body: "The description is not fully enough. Can you introduce me more?",
            files: []
        }
    );
    console.log("question", question);

    // WRITE A COMMENT
    const comment: ISaleArticleComment = await api.functional.shoppings.sales.comments.store
    (
        connection,
        "general",
        sale.id,
        question.id,
        {
            body: "p.s) Can you send me a detailed catalogue?",
            anonymous: false
        }
    );
    console.log("comment", comment);
}

Archidraw

https://www.archisketch.com/

I have special thanks to the Archidraw, where I'm working for.

The Archidraw is a great IT company developing 3D interior editor and lots of solutions based on the 3D assets. Also, the Archidraw is the first company who had adopted typescript-json on their commercial backend project, even typescript-json was in the alpha level.

저희 회사 "아키드로우" 에서, 삼촌과 함께 일할 프론트 개발자 분들을, 최고의 대우로 모십니다.

"아키드로우" 는 3D (인테리어) 에디터 및 이에 관한 파생 솔루션들을 만드는 회사입니다. 다만 저희 회사의 주력 제품이 3D 에디터라 하여, 반드시 3D 내지 랜더링에 능숙해야 하는 것은 아니니, 일반적인 프론트 개발자 분들도 망설임없이 지원해주십시오.

그리고 저희 회사는 분위기가 다들 친하고 즐겁게 지내는 분위기입니다. 더하여 위 nestiatypescript-jsonpayments 등, 제법 합리적(?)이고 재미난 프로젝트들을 다양하게 체험해보실 수 있습니다.

GitHub

https://github.com/samchon/typescript-json
Comments
  • 1. ReferenceError: is is not defined

    Bug Report

    Summary

    Write a short summary of the bug in here.

    • SDK Version: 3.0.2
    • Expected behavior: assertType should not throws, or should throws the correct error.
    • Actual behavior: always throw ReferenceError: is is not defined

    Write detailed description in here.

    With this type union there appears to be a bug in the generated code.

    Code occuring the bug

    import TSON from 'typescript-json'
    
    type A = { a: number } | { a: { a: number } }
    const a = JSON.parse('{"a": { "a": 123 } }')
    TSON.assertType<A>(a) //throws: "ReferenceError: is is not defined"
    
    Reviewed by edobrb at 2022-06-26 13:37
  • 2. Re-implement `application()` function

    Re-implement application() function like below.

    export function application<
        Types extends unknown[],
        Mode extends "swagger" | "ajv" = "swagger",
        Prefix extends string = Mode extends "swagger" 
            ? "#/components/schemas" 
            : "components#/schemas"
    >(): IJsonApplication
    
    Reviewed by samchon at 2022-06-11 19:22
  • 3. Move `crypto.randomUUID()` polyfill to `StringifyFactory`

    As typescript-json supports JSON schema generations, it would better to move crypto.randomUUID() polyfill from main file to the StringifyFactory, who generates the faster JSON.stringify() function.

    Reviewed by samchon at 2022-05-24 17:25
  • 4. Support implicit generic argument for the `TSON.stringify()`

    This should be possible:

    import TSON from "typescript-json";
    import { RandomGenerator } from "../internal/RandomGenerator";
    
    export function test_stringify_object_implicit(): void
    {
        const lecture: ILecture = {
            name: RandomGenerator.string(),
            professor: RandomGenerator.string(),
            grade: RandomGenerator.number()
        };
        const implicit: string = TSON.stringify(lecture);
        const explicit: string = TSON.stringify<ILecture>(lecture);
    }
    
    interface ILecture
    {
        name: string;
        professor: string;
        grade: number;
    }
    
    Reviewed by samchon at 2022-04-19 14:08
  • 5. Performance tuning by template literal

    Well, tried using Array.join() function to beautify compiled code, but it made json string conversion speed slowly. Also, comparing string concatenation and template literal, template literal is about 1.5x times faster.

    Therefore, utilize the template literal enhance performance

    Reviewed by samchon at 2022-06-18 20:36
  • 6. Don't let transformer to write import statement

    When a project using this typescript-json builds d.ts.map file, the import statement generated by transformer causes an error in the tsc --watch mode compilation.

    D:\github\samchon\nestia\node_modules\typescript\lib\typescript.js:2707
                throw e;
                ^
    
    Error: Debug Failure. False expression: File extension for signature expected to be dts
    Verbose Debug Information: Found: .map for D:/github/samchon/nestia/lib/generates/SdkGenerator.d.ts.map:: All output files: ["D:/github/samchon/nestia/lib/generates/SdkGenerator.d.ts.map","D:/github/samchon/nestia/lib/generates/SdkGenerator.d.ts"]
        at updateShapeSignature (D:\github\samchon\nestia\node_modules\typescript\lib\typescript.js:119846:30)
        at Object.getFilesAffectedBy (D:\github\samchon\nestia\node_modules\typescript\lib\typescript.js:119799:18)
        at getNextAffectedFile (D:\github\samchon\nestia\node_modules\typescript\lib\typescript.js:120285:51)
        at getSemanticDiagnosticsOfNextAffectedFile (D:\github\samchon\nestia\node_modules\typescript\lib\typescript.js:120964:32)
        at Object.getSemanticDiagnostics (D:\github\samchon\nestia\node_modules\typescript\lib\typescript.js:121009:20)
        at emitFilesAndReportErrors (D:\github\samchon\nestia\node_modules\typescript\lib\typescript.js:123038:57)
        at result.afterProgramCreate (D:\github\samchon\nestia\node_modules\typescript\lib\typescript.js:123229:13)
        at Object.watchCompilerHost.afterProgramCreate (D:\github\samchon\nestia\node_modules\typescript\lib\tsc.js:709:13)
        at synchronizeProgram (D:\github\samchon\nestia\node_modules\typescript\lib\typescript.js:123535:22)
        at updateProgram (D:\github\samchon\nestia\node_modules\typescript\lib\typescript.js:123750:21) 
    
    Reviewed by samchon at 2022-06-17 20:51
  • 7. No generator function required

    As v3 does not require any type or optimizer plan construction in the runtime, generator functions are never required. Erase them all.

    • createAssert
    • createIs
    • createStringify
    Reviewed by samchon at 2022-06-09 14:38
  • 8. Rename `createStringifier()` to `createStringify()`

    For the v3 update (#68), I've to implement those features. Looking for their names, it would better to rename ordinary createStringifier() to createStringify(), for the consistency. However, I'm considering whether to erase the legacy createStringifier() function or just tag the @deprecated symbol.

    • #70
    • #71
    Reviewed by samchon at 2022-06-06 11:05
  • 9. Revise README suitable for the `v3` update

    When #68 becomes come true, the README should be revised.

    Never forget to adding this title in the revised README

    1,000x times faster than fast-json-stringify

    Reviewed by samchon at 2022-06-06 10:40
  • 10. [V3] faster `JSON.stringify()` function by myself

    Implement faster JSON.stringify() function by myself.

    It would be v3 update and its JSON string conversion speed would be much faster than v2. The JSON string conversion speed would be 3x times faster than before (would be thoundands times faster when considering the optimizer plannig time). Also, the v3 does not utilize the JSON schema, but TypeScript type directly. Therefore, typescript-json would be much safer than ordinary v2.


    typescript-json is wrapper library of fast-json-stringify, which can omit JSON schema definition, through the TypeScript Compiler API with transformer. In such reason, providing maximum convenience to users with minimum effort was possible, by developing an automatic JSON schema generator. Furthermore, as typescript-json could define JSON schema automatically, dependent library like nestia could build swagger.json very easily.

    However, as adopted fast-json-stringify, typescript-json is following its disadvantages, too.

    At 1st, fast-json-stringify is not fast.

    The fast-json-stringify requires too much time to constructing faster JSON string conversion function. It analyzes JSON schema at runtime, therefore optimizing the JSON string conversion plan time is required, and it outcomes below result. As you can see from the below graph, optimizer planning time makes fast-json-stringify slower, than the native JSON.stringify(), about hundres times. Even measuring only JSON conversion speed, fast-json-stringify is slow too, when recursive relationshp comes.

    However, if I change typescript-json to optimize the JSON string conversion plan in the compilation level, through the TypeScript Compiler API with transformer, the conversion speed would not be slow by constructing the optimizer plan. Also, as typescript-json knows exact type of the target data, optimizer plan would be much evolved than before.

    • #60
    • #61

    Include optimizer planning time | Only JSON string conversion time ------------------------------------|------------------------------------------ image | image

    At 2nd, fast-json-stringify is not enough stable.

    fast-json-stringify is utilizing ajv library as dependency and the ajv library occurs an error when composite structured object type comes. Even the ajv is using non-standard feature $recursiveRef, which does not defined in the JSONS schema. However, the $recursiveRef be broken when complicated structure comes.

    However, if I develop JSON string conversion logic by myself, such bug would not be occured.

    • https://github.com/fastify/fast-json-stringify/issues/417
    • https://github.com/samchon/typescript-json/issues/42
    • https://github.com/samchon/typescript-json/issues/48
    • https://github.com/samchon/typescript-json/issues/48

    At last, TypeScript type is much superior than the JSON schema.

    Developing the JSON schema generator from the TypeScript type, I understood that how TypeScrip type is superior and how JSON schema is inferior, within framework of the TypeScript user. Therefore, when developing TypeScript library boosting up the JSON string conversion speed, using pure TypeScript type is much better.

    For example, fast-json-stringify and ajv cannot understand the Object.toJSON() method, because they don't know original types of parameters. With fast-json-stringify, to solve the below bug, custom JSON string conversion must check all of the values whether they're a type of object and has a toJSON() method or not, via recursive visit strategy. However, it would make JSON string conversion speed much slower.

    However, if v3 comes, the toJSON() methods would be exactly traced in the compilation level.

    • https://github.com/fastify/fast-json-stringify/issues/405
    • https://github.com/samchon/typescript-json/issues/28
    Reviewed by samchon at 2022-06-06 10:35
  • 11. Swagger editor is not supporting the tuple type

    https://github.com/swagger-api/swagger-editor/issues/2638

    The tuple type has been adopted in the OAS 3.1, but swagger editor is not supporting it.

    Therefore, when building JSON schema for swagger generation, use oneOf options instead.

    Reviewed by samchon at 2022-06-05 16:45
  • 12. 아키드로우 TypeScript/프론트 개발자 채용

    저희 회사 "아키드로우" 에서, 삼촌과 함께 일할 프론트 개발자 분들을, 최고의 대우로 모십니다.

    "아키드로우" 는 3D (인테리어) 에디터 및 이에 관한 파생 솔루션들을 만드는 회사입니다. 다만 저희 회사의 주력 제품이 3D 에디터라 하여, 반드시 3D 내지 랜더링에 능숙해야 하는 것은 아니니, 일반적인 프론트 개발자분들도 망설임없이 지원해주십시오.

    그리고 저희 회사는 분위기가 다들 친하고 즐겁게 지내는 분위기입니다. 더하여 위 typescript-json 이나 nestiapayments 등, 제법 합리적(?)이고 재미난 프로젝트들을 다양하게 체험해보실 수 있습니다.

    Reviewed by samchon at 2022-04-20 13:11
Quickly load Vue, React, SpriteJS components via command line

Faster way to render & interact react & vue3 components with command line interface.

Mar 9, 2022
This command line can be used to convert React class components to become functional components

class-to-function This command line can be used to convert React class components to become functional components. Installation Install it as a global

Mar 8, 2022
A React JS project to make age and gender prediction using Agify.io and Genderize.io. Only for practice use and just for fun~

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

May 29, 2022
Pinterest website clone with React and Redux only for learning purposes

Pinterest website clone with React and Redux only for learning purposes. Pinterest is an image sharing and social media service designed to enable saving and discovery of information on the internet using images, and on a smaller scale, animated GIFs and videos, in the form of pinboards.

Apr 6, 2022
An one-of-a-kind social network

An one-of-a-kind social network

Jun 8, 2022
An all in one preset for writing Preact apps with the vite bundler.

@preact/preset-vite An all in one preset for writing Preact apps with the vite bundler. Features: Sets up Hot Module Replacement via prefresh Enables

Jun 15, 2022
Estudo de ReactJS curso da Digital Innovation One

Práticas Avançadas em Projetos com ReactJS Repositório de estudo de ReactJS Ciclo de Vida do React - Aulas 01 a 03 Entendendo o ciclo de vida do React

Nov 4, 2021
💥 The best all-in-one toolbox. Bazinga!

?? The best all-in-one toolbox. Bazinga!

Jun 16, 2022
React JSON Viewer Component, Extracted from redux-devtools

This package was merged into redux-devtools monorepo. Please refer to that repository for the latest updates, issues and pull requests. react-json-tre

May 31, 2022
JSONX - Create React Elements, JSX and HTML from JSON

JSONX Description JSONX is a module that creates React Elements, JSX and HTML from JSON. Declarative The JSONX UMD comes with batteries included so yo

May 25, 2022
React Translator is a Web Interface created for make the creation of locales.json more easier.

React Translator is a Web Interface created for make the creation of locales.json more easier. Theses locales files can be used in the package @oneforx/react-translator

May 27, 2022
A better JSON differ & viewer, support LCS diff for arrays and recognise some changes as modification apart from simple remove+add.
A better JSON differ & viewer, support LCS diff for arrays and recognise some changes as modification apart from simple remove+add.

A better JSON differ & viewer, support LCS diff for arrays and recognise some changes as modification apart from simple remove+add.

Jun 25, 2022
A simple tool to view Facebook Messenger exported JSON files
A simple tool to view Facebook Messenger exported JSON files

Facebook Messenger exported JSON viewer What's this? This is a simple tool to view Facebook Messenger exported JSON files. I made the UI into a Messen

Jun 8, 2022
JWT generator - An open-source JSON Web Token (JWT) generator created by enabler
JWT generator -  An open-source JSON Web Token (JWT) generator created by enabler

JWT generator An open-source JSON Web Token (JWT) generator created by enabler View Demo · Report Bug JWT generator allows you to generate JWT in an e

May 31, 2022
Cheatsheets for experienced React developers getting started with TypeScript
Cheatsheets for experienced React developers getting started with TypeScript

Cheatsheets for experienced React developers getting started with TypeScript

Jun 19, 2022
A starter for React with Typescript with the fast Vite and all static code testing with Eslint and formatting with Prettier.
A starter for React with Typescript with the fast Vite and all static code testing with Eslint and formatting with Prettier.

A starter for React with Typescript with the fast Vite and all static code testing with Eslint and formatting with Prettier.

Jun 25, 2022
Quiz Machine - React Vite TypeScript

Quiz Machine - XState + React + Typescript + Vite Surge https://quiz-machine-react.surge.sh/ Github https://github.com/Krutie/quiz-machine-react-vite-

Jul 17, 2021
Projeto da 6 NLW de React da @Rocketseat, desenvolvido utilizando Firebase, Styled-Components e Typescript.
Projeto da 6 NLW de React da @Rocketseat, desenvolvido utilizando Firebase, Styled-Components e Typescript.

Letmeask ?? Crie salas de Q&A ao-vivo. Tire as suas dúvidas da sua audiência em tempo-real ?? Tecnologias usadas ReactJS + Typescript Styled-component

Jun 18, 2022
Uniswap V3 Fee Calculator created with React & Typescript
Uniswap V3 Fee Calculator created with React & Typescript

Uniswap V3 Fee Calculator created with React & Typescript

Jun 14, 2022