2025-01-28 04:05:31 +09:00
2024-12-25 07:40:46 +09:00
2025-01-28 02:39:50 +09:00
2025-01-28 02:39:50 +09:00
2025-01-28 02:39:50 +09:00
2025-01-26 03:27:38 +09:00
2025-01-28 02:39:50 +09:00
2024-12-24 23:31:06 +09:00
2025-01-28 02:39:50 +09:00
2025-01-26 07:10:35 +09:00
2025-01-28 02:39:50 +09:00
2025-01-28 02:39:50 +09:00
2025-01-28 04:05:31 +09:00
2025-01-26 03:27:38 +09:00
2025-01-28 02:39:50 +09:00

TypeMap

Unified Syntax, Mapping and Compiler System for Runtime Type Systems



npm version Downloads Build License

Install

$ npm install @sinclair/typemap --save

Usage

Create Types with TypeScript syntax.

import { Zod, Compile } from '@sinclair/typemap'

const result = Zod(`string`).parse('Hello World')

Overview

TypeMap is a syntax frontend and compiler backend for the TypeBox, Valibot and Zod type libraries. It provides a uniform syntax for creating types, a runtime compiler for high-performance validation and enables types written in one library to be transformed to another.

TypeMap is built as an advanced adapter system for the TypeBox project. It enables Valibot and Zod to be integrated on TypeBox validation infrastructure as well as enabling TypeBox to be integrated on Zod infrastructure via reverse type mapping.

License: MIT

Contents

Example

Construct types for TypeBox, Valibot and Zod using a common TypeScript syntax

Example Link

import { TypeBox, Valibot, Zod } from '@sinclair/typemap'

// Parse Syntax | Parse Value 

const R = Zod('string | number').parse('...')       // const R: string | number

// Common Syntax Type Representation

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
                                                    // }, ...>

Transform types between TypeBox, Valibot and Zod

Example Link

import { TypeBox, Valibot, Zod } from '@sinclair/typemap'

const JsonSchema = TypeBox(Valibot(Zod(`{
  x: number,
  y: number,
  z: number
}`)))

Compile Zod and Valibot on TypeBox validation infrastructure

Example Link

import { Compile } from '@sinclair/typemap'

import z from 'zod'

// Compile Zod Type

const C = Compile(z.object({                         // const C: Validator<TObject<{  
  x: z.number(),                                     //   x: TNumber,     
  y: z.number(),                                     //   y: TNumber,
  z: z.number(),                                     //   z: TNumber
}))                                                  // }>>   
                                  
const R = C.Check({                                  // Iterations: 10_000_000
  x: 1,                                              //
  y: 2,                                              // Zod        : 4000ms (approx)
  z: 3                                               // TypeMap    : 40ms   (approx)
})

Libraries

TypeMap, at its core, is a runtime type mapping library. It is specifically designed to transform types from one library into types for another.

TypeMap performs deep type mapping both statically (within the type system) and at runtime. As a rule, if a type cannot be mapped during traversal, the library function returns a never representation specific to the library being mapped for.

TypeBox

Use the TypeBox function to map a parameter into a TypeBox type.

import { TypeBox } from '@sinclair/typemap'

const A = TypeBox(t.Number())                  // const A: TNumber         (TypeBox)
const B = TypeBox(v.string())                  // const B: TString         (Valibot)
const C = TypeBox(z.boolean())                 // const C: TBoolean        (Zod)
const D = TypeBox('string[]')                  // const D: TArray<TString> (Syntax)

Valibot

Use the Valibot function to map the parameter into a Valibot type

import { Valibot } from '@sinclair/typemap'

const A = Valibot(t.Number())                  // const A: v.NumberSchema     (TypeBox)
const B = Valibot(v.string())                  // const B: v.StringSchema     (Valibot)
const C = Valibot(z.boolean())                 // const C: v.BooleanSchema    (Zod)
const D = Valibot('string[]')                  // const D: v.ArraySchema<...> (Syntax)

Zod

Use the Zod function to map the parameter into a Zod type

import { Zod } from '@sinclair/typemap'

const A = Zod(t.Number())                  // const A: z.ZodNumber     (TypeBox)
const B = Zod(v.string())                  // const B: z.ZodString     (Valibot)
const C = Zod(z.boolean())                 // const C: z.ZodBoolean    (Zod)
const D = Zod('string[]')                  // const D: z.ZodArray<...> (Syntax)

Syntax

TypeMap provides an optional syntax that can be used to construct runtime type representations. Syntax mapping is based on Syntax Type provided by TypeBox.

Types

Pass a constant string parameter with an embedded TypeScript type annotion to construct a type. If there is a syntax error, the function return type will be never.

Example Link

import { Zod } from '@sinclair/typemap'

// Create a Zod type and Parse it

const result = Zod('{ x: 1 }').parse({ x: 1 })

Options

Options can be passed on the last parameter of a syntax type. TypeMap understands Json Schema keyword constraints. Known constraints will be mapped to analogs structures for the target library if possible.

import { Zod } from '@sinclair/typemap'

// const T = z.string().email()

const T = Zod('string', {
  format: 'email' 
})

// const S = z.object({ x: z.number() }).strict()

const S = Zod('{ x: number }', { 
  additionalProperties: false 
})

Parameters

Syntax types can be parameterized to accept exterior types. The following injects a Zod type into a Valibot vector structure.

Example Link

import { Valibot, Zod } from '@sinclair/typemap'

// Construct T

const T = Zod('number')

// Pass T to S

const S = Valibot({ T }, `{ x: T, y: T, z: T }`)

Generics

Using type parameters, you can construct generic via functions.

Example Link

import { TypeBox, Valibot, Zod } from '@sinclair/typemap'

// Generic Vector Type | Function

const Vector = <T extends object>(T: T) => Valibot({ T }, 
  `{ x: T, y: T, z: T }`
)

// Number Vector Type

const NumberVector = Vector(TypeBox('number'))

// String Vector Type

const StringVector = Vector(Zod('string'))

Static

Use Static to uniformly infer for syntax and library 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.

import { Compile, Zod } from '@sinclair/typemap'

// Compile Zod Type

const V = Compile(Zod(`{
   x: number,
   y: number,
   z: number
}`))

// TypeMap Check Function

const R1 = V.Check({ x: 1, y: 2, z: 3 })

// Standard Schema Interface Check Function

const R2 = V['~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.

Description
No description provided
Readme 10 MiB
Languages
TypeScript 97.2%
JavaScript 2.8%