Revision 0.8.4 (#13)
* Parameterized Types * Syntax Options * Documentation
This commit is contained in:
233
readme.md
233
readme.md
@@ -2,9 +2,9 @@
|
||||
|
||||
<h1>TypeMap</h1>
|
||||
|
||||
<p>Uniform Syntax, Mapping and Compiler Library for TypeBox, Valibot and Zod</p>
|
||||
<p>Unified Syntax and Type Compiler for Runtime Type Systems</p>
|
||||
|
||||
<img src="https://github.com/sinclairzx81/typemap/blob/main/typemap.png?raw=true" />
|
||||
<img src="./typemap.png" />
|
||||
|
||||
<br />
|
||||
<br />
|
||||
@@ -22,16 +22,62 @@
|
||||
$ npm install @sinclair/typemap --save
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Create and Compile Runtime Types using TypeScript syntax.
|
||||
|
||||
```typescript
|
||||
import { Zod, Compile } from '@sinclair/typemap'
|
||||
|
||||
const T = Zod(`string`) // ZodString
|
||||
|
||||
const R = Compile(T).Check('Hello from TypeMap')
|
||||
```
|
||||
|
||||
## Overview
|
||||
|
||||
TypeMap is a syntax frontend and compiler backend for the [TypeBox](https://github.com/sinclairzx81/typebox), [Valibot](https://github.com/fabian-hiller/valibot) and [Zod](https://github.com/colinhacks/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
|
||||
|
||||
- [Install](#Install)
|
||||
- [Usage](#Usage)
|
||||
- [Overview](#Overview)
|
||||
- [Example](#Example)
|
||||
- [Libraries](#Libraries)
|
||||
- [TypeBox](#TypeBox)
|
||||
- [Valibot](#Valibot)
|
||||
- [Zod](#Zod)
|
||||
- [Syntax](#Syntax)
|
||||
- [Types](#Types)
|
||||
- [Options](#Options)
|
||||
- [Parameters](#Parameters)
|
||||
- [Generics](#Generics)
|
||||
- [Static](#Static)
|
||||
- [Compile](#Compile)
|
||||
- [Benchmark](#Benchmark)
|
||||
- [Contribute](#Contribute)
|
||||
|
||||
## Example
|
||||
|
||||
Use TypeScript syntax to construct types for TypeBox, Valibot and Zod ...
|
||||
Construct types for TypeBox, Valibot and Zod using a common TypeScript syntax
|
||||
|
||||
[Example Link](https://www.typescriptlang.org/play/?moduleResolution=99&module=199#code/JYWwDg9gTgLgBAbzgFQJ5gKYCEIA8A0cAagIYA2wARhDIQFoQAmcAvnAGZQQhwDkAAgGdgAOwDGZEsCgB6GOgwgSYXgChVMmSgUBlMVGBh4O1CJglc2zOrEQRg43AC8cAAYJVcOLgBccEQCuIJQYUPiecKh+gcGh4V4AXtFBIVCqLK7qmnAAwnYOUAFi8AAyVFAkUKhWGIIcXDwmZhY2+fDIzjU4uAAUOgCUXkPDI6NjI9m29u1+yADylABWGMUAPB7jm1vbO17ZXr4oAHIpcRG7F5fj+5GzJ7Fh51fPVzdJx6dpL9+X2SwAfK1psROqQKNQYH1Bj9tpM2sQ-AtlsU9AALRQkdZPGE4iZaA5+e6pNEY1ZYEiCDAAUSgXCg-3iuKZwxuUTgRNCJKUZIp1Np0AZ2OZOLehM+XMx5MpNLpgOFwr+hAAdCrAUCHHA6J0GIwofLNnDgXQ-DqkSsYFj9UybocdRzHlbcayTUx7YzHT9RZrXZ8hR7floWMrVX7nhotAAFSqUuBNcyWAA+cCjUBjaEwcHV8AAStqmFClWBoxgerwVUreNCYYaNdm-Bt-d8bckHgBuUON2H427+T7tzsvL0xVL9gevQNAA)
|
||||
[Example Link](https://www.typescriptlang.org/play/?moduleResolution=99&module=199#code/JYWwDg9gTgLgBAbzgFQJ5gKYCEIA8A0cAagIYA2wARhDIQFoQAmcAvnAGZQQhwDkAAgGdgAOwDGZEsCgB6GOgwgSYXgChVMmXAAKJKIIxwAyqhEwSuOAB8deg8XIBXQ+rEQRg+ACU4AXjgMjAAUvJ5QogDm1nAijiCUGFC8AJQAdGB2GCGpOSlw+QVwmnBuHt4AXHBhkdGx8YnqxQDC3CDuxqbmlmiYcF4YYFAYBmYkMMDuru6exn5wAAYIqvm4lXUJUPjLcKhrcRtb+QBee-VQqizzU2Uocz3YeEFGyYWvb+8f+cWlM8iVyAB5SgAKwwYhgAB4lp8YbC4TDiit-gA5faJQ7wzFYz6InYotGbbbY4nE3EnFCos5Ekk0uHFFgAPmuMyIc1IFGoMCeL1psO+03gREqQNB4KMYgAFooSFDqbz5a9cas4JSNuKpUoITlUgyMQr9QVcbsVQT1dKtTldXKDfKyZVVYkzZrtUybTb6YQXepVD94HQ5oFuW6cVpfQFKoERWDIdDgwqlRGmA7CXH41p8sbAsm9amaXaAkmCdbc1iPXAXUA)
|
||||
|
||||
```typescript
|
||||
import { TypeBox, Valibot, Zod } from '@sinclair/typemap'
|
||||
|
||||
// TypeScript Syntax Type
|
||||
// Parse Syntax | Parse Value
|
||||
|
||||
const R = Zod('string | number').parse('...') // const R: string | number
|
||||
|
||||
// Common Syntax Type Representation
|
||||
|
||||
const S = `{
|
||||
x: number,
|
||||
@@ -39,8 +85,6 @@ const S = `{
|
||||
z: number
|
||||
}`
|
||||
|
||||
// Construct Library Types from Syntax
|
||||
|
||||
const T = TypeBox(S) // const T: TObject<{
|
||||
// x: TNumber,
|
||||
// y: TNumber,
|
||||
@@ -59,80 +103,55 @@ const Z = Zod(S) // const Z: ZodObject<{
|
||||
// y: ZodNumber,
|
||||
// z: ZodNumber
|
||||
// }, ...>
|
||||
|
||||
// Parse Syntax | Parse Value
|
||||
|
||||
const R = Zod('string | number').parse('...') // const R: string | number
|
||||
```
|
||||
|
||||
... or structurally remap types from one library to another
|
||||
Transform types between TypeBox, Valibot and Zod
|
||||
|
||||
[Example Link](https://www.typescriptlang.org/play/?moduleResolution=99&module=199#code/JYWwDg9gTgLgBAbzgFQJ5gKYCEIA8A0cAagIYA2wARhDIQFoQAmcAvnAGZQQhwDkAAgGdgAOwDGZEsCgB6GOgwgSYXgChVMmXADKqETBK44APjgNmp0hWrxTaTDlzqxEEYPjI4AXhQLHACisqGn9zfwADBFU4OFwALjgRAFcQSgwofGi4VATk1PTMmIAvXJS0qFUWcIBKWqA)
|
||||
[Example Link](https://www.typescriptlang.org/play/?moduleResolution=99&module=199#code/JYWwDg9gTgLgBAbzgFQJ5gKYCEIA8A0cAagIYA2wARhDIQFoQAmcAvnAGZQQhwDkAAgGdgAOwDGZEsCgB6GOgwgSYXgChVYiCMHwAUoK0BlMQAtFJOAF4UCnLgAUpCtRj2GjewAMEquHFwAXHAiAK4glBhQ+L5wqEGh4ZHRfgBe8WERUKosngCU+UA)
|
||||
|
||||
```typescript
|
||||
import { TypeBox, Valibot, Zod } from '@sinclair/typemap'
|
||||
|
||||
// Syntax > Zod > Valibot > TypeBox
|
||||
|
||||
const T = TypeBox(Valibot(Zod(`{
|
||||
const JsonSchema = TypeBox(Valibot(Zod(`{
|
||||
x: number,
|
||||
y: number,
|
||||
z: number
|
||||
}`)))
|
||||
```
|
||||
|
||||
... or compile types for high performance runtime type checking
|
||||
Compile Zod and Valibot on TypeBox validation infrastructure
|
||||
|
||||
[Example Link](https://www.typescriptlang.org/play/?moduleResolution=99&module=199#code/JYWwDg9gTgLgBAbzgYQuYAbApnAvnAMyjTgHIABAZ2ADsBjDAQ2CgHoYBPMLERsUgFADQkWHABehYiDLiIAE0EC6EGpXgAVOAF4JAOggAjAFZY6MABRI4N23butWcFWs0AufQC0FAeRNmYAB4kARsADw9xPRoAVxBDLCgLAEoAGnsMzLhHWwivBQA5OISoVNC4Dkjo4sSU9KyG7KcbSvz5IvjEsptxKtjOpLTGhpyequ92mtKBXGTh+cac3AA+IRd1FB0UNDBMLAsNOYWm51UN5A8ANUYMYHlGGGhAjT9Tc2Dy46+HZrg8jQ6JW63xBJxaHgBU2BoK+owkEMBiU+MIWS2Wy1sazO8AASltkHpkAALMwAays3xy61xHkMEAg2EYNDgAFo4AAJYAAcyJcAACokCNBePQcMSybQuQBCcp5ACMwNaACZ0uVenAAMwzZJAA)
|
||||
[Example Link](https://www.typescriptlang.org/play/?moduleResolution=99&module=199&ssl=17&ssc=3&pln=1&pc=1#code/JYWwDg9gTgLgBAbzgYQuYAbApnAvnAMyjTgHIABAZ2ADsBjDAQ2CgHoYBPMLERsUgFADQkWHABehYiDLiIAE0EDWrFGjCYcALQVwAKlyxC6EGpXjI4AXjXpsACnEA6CACMAVljox7SOP4DAoOCAlTgTMwsALjgANUYMYHlGGGgAHj0AeQ8vGDS-AX8ADxjnGgBXEFcsKHsASgAaEOaW1tDVYpi9ADlK6qgmwMK4DlKnCqqa+sG22dmw-1H9XsmB4fExif7pud3WhYkulf6BXDq6vcur-zDcAD47gOHr3YEI8zgAJWsUJ2QACy8AGtfC89mEAJIwGopYCmSgxACMAAYAPrIjHojHDEpwREzMGEm6sYZLABMBKJYLCOnkzRiABYMciQJQ4PY+GBiEU6usYgBmKlCsIGbgAWT4gUZLLZ-g5YC5EB5pzqQA)
|
||||
|
||||
```typescript
|
||||
import { Compile } from '@sinclair/typemap'
|
||||
|
||||
import z from 'zod'
|
||||
|
||||
const T = Compile(z.object({ // const T: Validator<TObject<{
|
||||
// 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 = T.Check({ // High Performance Check
|
||||
x: 1,
|
||||
y: 2,
|
||||
z: 3
|
||||
const R = C.Check({ // Iterations: 10_000_000
|
||||
x: 1, //
|
||||
y: 2, // Zod : 4000ms (approx)
|
||||
z: 3 // TypeMap : 40ms (approx)
|
||||
})
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Overview
|
||||
|
||||
TypeMap is a type mapping library developed for the [TypeBox](https://github.com/sinclairzx81/typebox), [Valibot](https://github.com/fabian-hiller/valibot) and [Zod](https://github.com/colinhacks/zod) runtime type libraries. It is designed to make these libraries cross compatible by structurally remapping types from one library to another. TypeMap also provides a uniform frontend syntax for creating types, as well as uniform type compilation for high-performance validation via the TypeBox compiler infrastructure.
|
||||
|
||||
TypeMap is built to be a simple tool to let Valibot and Zod to integrate with TypeBox and Json Schema infrastructure. It is also written to enable TypeBox to integrate with systems using Valibot and Zod for validation.
|
||||
|
||||
License: MIT
|
||||
|
||||
## Contents
|
||||
|
||||
- [Install](#Install)
|
||||
- [Overview](#Overview)
|
||||
- [Libraries](#Libraries)
|
||||
- [TypeBox](#TypeBox)
|
||||
- [Valibot](#Valibot)
|
||||
- [Zod](#Zod)
|
||||
- [Static](#Static)
|
||||
- [Compile](#Compile)
|
||||
- [Benchmark](#Benchmark)
|
||||
- [Contribute](#Contribute)
|
||||
|
||||
## Libraries
|
||||
|
||||
TypeMap exports mapping functions named after the library they map for. Each function can accept a type from any other library, where the function will attempt to map the type or return a `never` representation if a mapping is not possible.
|
||||
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 the parameter into a TypeBox type
|
||||
Use the TypeBox function to map a parameter into a TypeBox type.
|
||||
|
||||
```typescript
|
||||
import { TypeBox } from '@sinclair/typemap'
|
||||
@@ -169,9 +188,90 @@ 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](https://github.com/sinclairzx81/typebox?#syntax) 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](https://www.typescriptlang.org/play/?moduleResolution=99&module=199#code/JYWwDg9gTgLgBAbzgLQgEzgXzgMyhEOAcgAEBnYAOwGMAbAQ2CgHoYBPMAUxHrCICh+zZnADCUTvRic49FOjjsusyhgAK9KGRnAYg6hEpl4EsgFda8ALzy0ACiJIAHgC44ARixEAlADowmtp2zm6emN5AA)
|
||||
|
||||
```typescript
|
||||
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.
|
||||
|
||||
```typescript
|
||||
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](https://www.typescriptlang.org/play/?moduleResolution=99&module=199#code/JYWwDg9gTgLgBAbzgNQIYBtgCMIwDRwBaEAJnAL5wBmUEIcA5AAIDOwAdgMbqrBQD0MAJ5gApiFRgGAKGn9+cAMIR2LGFACuneABVZnFWrg64AXiKkAFA3YaQWUVAYBKWfLgAFVCxbG4MCDgAZX1DeCCzFAxsXEskE3ICAAMkAA8ALmMCIUydAgAvXIok5yA)
|
||||
|
||||
```typescript
|
||||
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](https://www.typescriptlang.org/play/?moduleResolution=99&module=199#code/JYWwDg9gTgLgBAbzgFQJ5gKYCEIA8A0cAagIYA2wARhDIQFoQAmcAvnAGZQQhwDkAAgGdgAOwDGZEsCgB6GOgwgSYXgChVMmXADiGERijAxxDGJjQUCuAB84AMQCu4mMAgj1Yt4PhFT5qHAAvHAAPMhwGLgweoyCcBCUAFZ+AHwAFMgAXCgAlEEpxORUNGlI4SyEqnBwAAZIuNnIhKiNhABejaw1qjnqmnAAcg4glAYmZhZomB5e8EMjBr4TAcFL-hkKOLhpvCLDo1C8Ob0aWgDKMIYiAObj-pbTqp4i3nAXV9drFqt+0GkMjB23g+RxyQA)
|
||||
|
||||
```typescript
|
||||
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
|
||||
|
||||
TypeMap can statically infer for TypeBox, Valibot, Zod and Syntax with the `Static` type.
|
||||
Use Static to uniformly infer for syntax and library types
|
||||
|
||||
```typescript
|
||||
import { type Static } from '@sinclair/typemap'
|
||||
@@ -189,32 +289,33 @@ type S = Static<typeof S> // string[]
|
||||
|
||||
## Compile
|
||||
|
||||
TypeMap offers JIT compilation of TypeBox, Valibot, Zod and Syntax using the `Compile` function. This function will internally use the TypeBox TypeCompiler for high performance checking. This function will also gracefully degrade to dynamic checking if the runtime does not support JavaScript evaluation.
|
||||
|
||||
The `Compile` function returns a validator object that implements the [standard-schema](https://github.com/standard-schema/standard-schema) interface.
|
||||
Use the Compile function to compile Zod and Valibot on TypeBox validation infrastructure.
|
||||
|
||||
```typescript
|
||||
import { Compile } from '@sinclair/typemap'
|
||||
import { Compile, Zod } from '@sinclair/typemap'
|
||||
|
||||
// Pass TypeBox, Valibot, Zod or Syntax to JIT Compile the type.
|
||||
const V = Compile(`{
|
||||
x: number
|
||||
y: number,
|
||||
z: number
|
||||
}`)
|
||||
// Compile Zod Type
|
||||
|
||||
const V = Compile(Zod(`{
|
||||
x: number,
|
||||
y: number,
|
||||
z: number
|
||||
}`))
|
||||
|
||||
// TypeMap Check Function
|
||||
|
||||
// TypeMap Interface
|
||||
const R1 = V.Check({ x: 1, y: 2, z: 3 })
|
||||
|
||||
// Standard Schema Interface
|
||||
// Standard Schema Interface Check Function
|
||||
|
||||
const R2 = V['~standard'].validate({ x: 1, y: 2, z: 3 })
|
||||
```
|
||||
|
||||
## Benchmark
|
||||
|
||||
This project manages a benchmark that evaluates type-check performance using Zod, Valibot, and TypeBox validators. The benchmark is set up to run 10 million check operations per library-validator pairing and reports the elapsed time taken to complete.
|
||||
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](https://github.com/moltar/typescript-runtime-type-benchmarks) project.
|
||||
|
||||
### Type
|
||||
### Test
|
||||
|
||||
Benchmarks are run for the following type.
|
||||
|
||||
@@ -224,7 +325,7 @@ type T = { x: number, y: string, z: boolean }
|
||||
|
||||
### Results
|
||||
|
||||
Results show validate performance for the type.
|
||||
Results show the approximate elapsed time to complete the given iterations
|
||||
|
||||
```typescript
|
||||
┌─────────┬────────────────┬────────────────────┬────────────┬────────────┐
|
||||
@@ -243,9 +344,9 @@ Results show validate performance for the type.
|
||||
└─────────┴────────────────┴────────────────────┴────────────┴────────────┘
|
||||
```
|
||||
|
||||
For community benchmarks, refer to the [runtime-type-benchmarks](https://github.com/moltar/typescript-runtime-type-benchmarks) project.
|
||||
|
||||
|
||||
## Contribute
|
||||
|
||||
This project is open to community contributions. Please ensure you submit an open issue before creating a pull request. TypeMap encourages open community discussion before accepting new features.
|
||||
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.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user