Giter Site home page Giter Site logo

bung87 / typecheck.macro Goto Github PK

View Code? Open in Web Editor NEW

This project forked from vedantroy/typecheck.macro

0.0 2.0 0.0 395 KB

The fastest and easiest Typescript validation library. Automatically generate validation functions.

TypeScript 57.82% JavaScript 8.76% Nim 33.42%

typecheck.macro's Introduction

typecheck.macro

Babel Macro

Automatically generate 🔥blazing🔥 fast validators for Typescript types.

This project is in beta but it has been tested against established libraries, like ajv, to ensure it is reliable and doesn't make mistakes.

Example

type Cat<T> = {
    breed: "tabby" | "siamese";
    isNice: boolean;
    trinket?: T;
}
register('Cat')
const isNumberCat = createValidator<Cat<number>>()
isNumberCat({ breed: "tabby", isNice: false })                 // true
isNumberCat({ breed: "corgi", isNice: true, trinket: "toy" })  // false

Purpose

Because Typescript types are erased at compile time you can't use them to validate data at runtime. For example, you might want to ensure an API is returning data that matches a given type at runtime. This library (macro) generates validation functions for your Typescript types at compile time.

Why this library/macro?

Ease of Use

With typecheck.macro you can write normal Typescript types and automatically get validation functions for them. Other validation libraries require you to write your types in a DSL. Thus, typecheck.macro naturally integrates into your project without requiring you to change any existing code.

typecheck.macro supports validating interfaces, generics, tuples, unions, index signatures, optional properties, and more so you can validate most of your existing types automatically.

Performance

typecheck.macro generates specialized validation functions for each type that are pure Javascript. (Almost) every other library generates generic data structures that are plugged into a generic validator function.

typecheck.macro is up to 3x faster than ajv, the fastest JSON schema validator. And anywhere from 6 to 500 times faster than popular libraries, like runtypes or zod.

All comparisons are friendly in nature

Installation

If you are using Gatsby or Create React App, you can just install the macro. No other steps needed! (Most likely, I haven't tried it personally, so let me know what happens!)

Otherwise, you will need to switch over to compiling your Typescript with Babel. This isn't difficult since Babel has good Typescript support. See the example.

Then install babel-plugin-macros and add it to your babel config.

Finally, npm install typecheck.macro

Let me know if you have any installation issues, I will respond.

Usage

In addition to reading this, read the example.

import createValidator, { register } from 'typecheck.macro'

type A = {index: number, name: string}
register('A')
// named type
const validator = createValidator<A>()
// anonymous type
const validator2 = createValidator<{index: number, name: string}>()
// mix and match (anonymous type that contains a named type)
const validator3 = createValidator<{index: number, value: A}>()

register(typeName: string)

If you want to validate a named type or an anonymous type that references a named type, you must register the named type.

typeName is the name of the type you want to register. The type declaration must be in the same scope of the call to register.

{
    type A = {val: string}
    register('A') // registers A
    {
        register('A') // does nothing :(
    }
}
register('A') // does nothing :(

All registered types are stored in a global namespace.

register automatically registers all types in the same scope as the original type it is registering that are referred to by the original type.

type A = {val: string}
type B = {val: A}
type C = {val: A}
// registers A and B, but not C, since B only refers to A.
register('B')

All instances of the register macro are evaluated before any instance of createValidator. So ordering doesn't matter.

Because register stores types in a global namespace for your entire project, make sure all your registered types have different names.

Most of the primitive types (string, number, etc.) are already registered for you. As are Array and ReadonlyArray.

createValidator<T>(): (value: unknown) => value is T

Creates a validator function for the type T.

T can be any valid supported Typescript type. This includes any named type, anonymous type, or anonymous type that has references to named types.

At compile time, the call to register will be replaced with the generated code.

Support Tables

See the exec tests to get a good idea of what is supported

Primitives Types

Primitives Support
number Yes
string Yes
boolean Yes
object Yes
any Yes
unknown Yes
BigInt WIP
Symbol WIP

Builtin Generic Types

Type Support Notes
Array Yes
ReadonlyArray Yes Same as Array at runtime.
Map WIP
ReadonlyMap WIP Same as Map at runtime.
Record WIP

Typescript Concepts

Language Features Support Notes
interface Yes extending another interface is WIP
type alias Yes
generics Yes
union types Yes
tuple types Yes
arrays Yes
index signatures Yes
literal types Yes
circular references WIP
parenthesis type expressions WIP
intersection types WIP
Mapped Types WIP
classes No

Performance Table

The numbers are nanoseconds.

In the interest of fairness, typecheck.macro (currently) does not generate error messages (this is a WIP feature). It returns a boolean value indicating whether the given object matches the type. Thus, typecheck.macro does less work than the other libraries. However, typecheck.macro should still be faster, even if it generates error messages, because it generates efficient Javascript code while the other libraries (except ajv, which is also extremely fast) do not perform code generation.

Furthermore, typecheck.macro has not had any real performance/code generation optimizations yet, so the generated code will become even faster over time.

Library Simple Complex Notes
typecheck.macro 46 105
ajv 108 331
io-ts 235
runtypes 357
zod 11471 zod throws an exception upon validation error, which resulted in this extreme case

Generate data with pnpm run bench:prep and run a benchmark with pnpm run bench -- [macro|ajv|io-ts|runtypes|zod] --only=[simple|complex] where only is an optional flag.

Caveats

  • typecheck.macro currently allows extra keys to pass validation. This is consistent with the behavior of type aliases in Typescript, but different from the behavior of interfaces. Disallowing extra keys is a WIP feature.
  • typecheck.macro does not handle circular references

Contributing

Read the contributor docs. Contributions are welcome and encouraged!

typecheck.macro's People

Contributors

vedantroy avatar bung87 avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.