* Parameterized Compile Types * Documentation | Tests * Infer Validator via Static * Version
Install
$ npm install @sinclair/typemap --save
Usage
Parse and Compile Types from TypeScript syntax (Example)
import { Compile } from '@sinclair/typemap'
const result = Compile('string | null').Parse('Hello World')
Overview
TypeMap is a syntax frontend and compiler backend for the TypeBox, Valibot and Zod type libraries. It provides a common TypeScript syntax for type construction, a runtime compiler for high-performance validation and provides type translation from one library to another.
TypeMap is built as an advanced adapter and integration mechanism for the TypeBox project. It is designed to integrate and accelerate remote libraries by mapping them to TypeBox and Json Schema compatible infrastructure as well as allowing TypeBox to integrate on Zod specific infrastructure via reverse type mapping. This library is also written to offer high-performance validation for systems that orientate around the Standard Schema TypeScript interface.
License: MIT
Contents
Example
Use a TypeScript syntax to create types for TypeBox, Valibot and Zod (Example)
import { TypeBox, Valibot, Zod } from '@sinclair/typemap'
// Parse Syntax | Parse Value
const R = Zod('string | number').parse('...') // const R: string | number
// TypeScript Syntax
const S = `{
x: number,
y: number,
z: number
}`
const T = TypeBox(S) // const T: TObject<{
// x: TNumber,
// y: TNumber,
// z: TNumber
// }>
const V = Valibot(S) // const V: ObjectSchema<{
// x: NumberSchema<...>,
// y: NumberSchema<...>,
// z: NumberSchema<...>
// }, ...>
const Z = Zod(S) // const Z: ZodObject<{
// x: ZodNumber,
// y: ZodNumber,
// z: ZodNumber
// }, ...>
Parse and map between TypeBox, Valibot and Zod types (Example)
import { TypeBox, Valibot, Zod } from '@sinclair/typemap'
// Syntax -> Zod -> Valibot -> TypeBox
const T = TypeBox(Valibot(Zod(`{
x: number,
y: number,
z: number
}`)))
Compile Valibot and Zod types on TypeBox validation infrastructure. (Example)
import { Compile } from '@sinclair/typemap'
import z from 'zod'
// Zod Type
const Z = z.object({ // const Z: ZodObject<{
x: z.number(), // x: ZodNumber,
y: z.number(), // y: ZodNumber,
z: z.number(), // z: ZodNumber
}) // }>
// Remap and Compile
const C = Compile(Z) // const C: Validator<TObject<{
// x: TNumber,
// y: TNumber,
// z: TNumber
// }>>
// High Throughout Validation
const R = C.Check({ // Iterations: 10_000_000
x: 1, //
y: 2, // Zod : 4000ms (approx)
z: 3 // TypeMap : 40ms (approx)
})
Mapping
TypeMap is principally a runtime mapping library used for type translation. It provides a mapping function per translatable library which is used to map remote types and schematics into that library. If no translation is possible, these functions return a never representation specific to the library being mapped.
TypeBox
Use the TypeBox function to translate types and syntax into TypeBox types.
import { TypeBox } from '@sinclair/typemap'
const S = type('string[]') // const S: TArray<TString> (Syntax)
const T = type(t.Number()) // const T: TNumber (TypeBox)
const V = type(v.string()) // const V: TString (Valibot)
const Z = type(z.boolean()) // const Z: TBoolean (Zod)
Valibot
Use the Valibot function to translate types and syntax into Valibot types.
import { Valibot } from '@sinclair/typemap'
const S = Valibot('string[]') // const S: v.ArraySchema<...> (Syntax)
const T = Valibot(t.Number()) // const T: v.NumberSchema (TypeBox)
const V = Valibot(v.string()) // const V: v.StringSchema (Valibot)
const Z = Valibot(z.boolean()) // const Z: v.BooleanSchema (Zod)
Zod
Use the Zod function to translate types and syntax into Zod types.
import { Zod } from '@sinclair/typemap'
const S = Zod('string[]') // const S: z.ZodArray<...> (Syntax)
const T = Zod(t.Number()) // const T: z.ZodNumber (TypeBox)
const V = Zod(v.string()) // const V: z.ZodString (Valibot)
const Z = Zod(z.boolean()) // const Z: z.ZodBoolean (Zod)
Syntax
TypeMap provides a TypeScript syntax parser that can be used to create types. TypeScript parsing is implemented at runtime as well as in the TypeScript type system.
Types
Syntax types can be created by passing a string parameter to any ibrary mapping function. TypeMap supports most TypeScript annotation syntax. If the string contains a syntax error, the function will return a never type. (Example)
import { TypeBox } from '@sinclair/typemap'
const T = TypeBox('{ x: 1 }') // const T: TObject<{
// x: TLiteral<1>
// }>
const S = TypeBox('!!!') // const S: TNever
Options
Options can be passed on the last parameter of a type. TypeMap will translate known Json Schema keywords into appropriate runtime representations if possible. (Example)
import { TypeBox, Zod } from '@sinclair/typemap'
const T = TypeBox('string', { // const T: TString = {
format: 'email' // type: 'string',
}) // format: 'email'
// }
const S = Zod('{ x: number }', { // const S = z.object({
additionalProperties: false // x: z.number()
}) // }).strict()
Parameters
Types can be parameterized to accept exterior types. (Example)
import { Valibot, Zod } from '@sinclair/typemap'
const T = Valibot('number') // const T: NumberSchema
// Parameter T auto remapped to target library
const S = Zod({ T }, `{ x: T }`) // const S: ZodObject<{
// x: ZodNumber
// }, { ... }>
Generics
Use parameterized types with functions to create generic types (Example)
import { TypeBox, Valibot, Zod } from '@sinclair/typemap'
// Generic Type
const Vector = <T extends object>(T: T) => TypeBox({ T }, `{ x: T, y: T, z: T }`)
// Instanced Types
const T = Vector(Valibot('number')) // const N: TObject<{
// x: TNumber,
// y: TNumber,
// z: TNumber,
// }>
const S = Vector(Zod('number')) // const S: TObject<{
// x: TString,
// y: TString,
// z: TString,
// }>
Static
Use Static to infer for library and syntax types
import { type Static } from '@sinclair/typemap'
const T = t.Number() // TypeBox
const V = v.string() // Valibot
const Z = z.boolean() // Zod
const S = 'string[]' // Syntax
type T = Static<typeof T> // number
type V = Static<typeof V> // string
type Z = Static<typeof Z> // boolean
type S = Static<typeof S> // string[]
Compile
Use the Compile function to compile Zod and Valibot on TypeBox validation infrastructure. (Example)
import { Compile, Zod } from '@sinclair/typemap'
// Compile Validator From Zod
const validator = Compile(Zod(`{
x: number,
y: number,
z: number
}`))
const R1 = validator.Check({ x: 1, y: 2, z: 3 })
// Standard Schema
//
// ... which should have been named 'Standard Validator'
const R2 = validator['~standard'].validate({ x: 1, y: 2, z: 3 })
Benchmark
This project manages a small benchmark that compares validation performance using Zod, Valibot, and TypeBox validators. For more comprehensive community benchmarks, refer to the runtime-type-benchmarks project.
Test
Benchmarks are run for the following type.
type T = { x: number, y: string, z: boolean }
Results
Results show the approximate elapsed time to complete the given iterations
┌─────────┬────────────────┬────────────────────┬────────────┬────────────┐
│ (index) │ library │ using │ iterations │ elapsed │
├─────────┼────────────────┼────────────────────┼────────────┼────────────┤
│ 0 │ 'valibot ' │ 'valibot ' │ 10000000 │ '1534 ms ' │
│ 1 │ 'valibot ' │ 'typebox:value ' │ 10000000 │ '1377 ms ' │
│ 2 │ 'valibot ' │ 'typebox:compile ' │ 10000000 │ '46 ms ' │
└─────────┴────────────────┴────────────────────┴────────────┴────────────┘
┌─────────┬────────────────┬────────────────────┬────────────┬────────────┐
│ (index) │ library │ using │ iterations │ elapsed │
├─────────┼────────────────┼────────────────────┼────────────┼────────────┤
│ 0 │ 'zod ' │ 'zod ' │ 10000000 │ '4669 ms ' │
│ 1 │ 'zod ' │ 'typebox:value ' │ 10000000 │ '1359 ms ' │
│ 2 │ 'zod ' │ 'typebox:compile ' │ 10000000 │ '47 ms ' │
└─────────┴────────────────┴────────────────────┴────────────┴────────────┘
Contribute
This project is open to community contributions. Please ensure you submit an open issue before creating a pull request. TypeBox and associated projects preference open community discussion before accepting new features.
