$ npm install typedriver --saveCompile TypeScript definitions into high performance validators
import compile from 'typedriver'
const Vector = compile(`{
x: number
y: number
z: number
}`)
const value = Vector.parse(data) // const value: {
// x: number,
// y: number,
// z: number
// } = ...Syntax highlighting is available via the Visual Studio Marketplace
TypeDriver is a runtime type system that compiles TypeScript, JSON Schema and Standard Schema definitions into high performance JSON Schema validators. It also statically emulates the TypeScript type system inside the TypeScript type system which enables it to infer types from strings.
License MIT
TypeScript | JSON Schema | Standard Schema
The compile function will accept any TypeScript, JSON Schema or Standard Schema definition and JIT compile it into a high-performance runtime validator. If the JavaScript environment does not support JIT (i.e. Cloudflare), the compiler will automatically fallback to dynamic validation.
import compile from 'typedriver'const User = compile(`{
name: string
}`)const User = compile({
type: 'object',
required: ['name'],
properties: {
name: {
type: 'string'
}
}
})const User = compile(z.object({
name: z.string(),
}))TypeDriver validators have three validation functions.
Use parse for check-and-return, otherwise throw
const { x, y, z } = Vector.parse(data)Use check for fast boolean result
if(Vector.check(data)) {
const { x, y, z } = data
}Use errors to get diagnostics after a failed check
const errors = Vector.errors(data, {
format: 'standard-schema', // (default) 'json-schema'
locale: 'ko_KR' // (default) 'en_US'
})
console.log(errors)Definitions | Options | Generics | Programmable
TypeDriver has advanced type inference support for TypeScript definitions encoded as strings.
Type definitions can be specified in the following way.
const Address = `{
street: string
city: string
country: string
}`
const User = `{
name: string
email: string
address: ${Address}
}`
const Product = `{
id: string
name: string
price: number
}`
const Order = `{
user: ${User}
products: ${Product}[]
}`
const validator = compile(Order) // const validator: TValidator<{
// user: {
// name: string;
// email: string;
// address: {
// street: string;
// city: string;
// country: string;
// };
// };
// products: {
// name: string;
// id: string;
// price: number;
// }[];
// }>Data constraints and annotations can be specified via a with keyword. TypeDriver natively understands JSON Schema vocabulary. The following constrains a Vector type.
const Vector = compile(`{
x: number with { minimum: 0, maximum: 1 },
y: number with { minimum: 0, maximum: 1 }
} with {
description: '2D Vector Type'
}`)
console.log(Vector.toJsonSchema()) // {
// type: 'object',
// required: [ 'x', 'y' ],
// properties: {
// x: {
// type: 'number',
// minimum: 0,
// maximum: 1
// },
// y: {
// type: 'number',
// minimum: 0,
// maximum: 1
// }
// },
// description: '2D Vector Type'
// }Generic types can be created in the following way
const Generic = <T extends string>(T: T) => `{
x: ${T},
y: ${T}
}` as const
const TVector = Generic('number') // const TVector: `{
// x: number,
// y: number
// }` = `...`
const Vector = compile(TVector) // const Vector: TValidator<{
// x: number
// y: number
// }>Programmable mapped and conditional types are supported
import { compile } from 'typedriver'
const Input = `{
x: number
y: number
z: number
}`
const Output = `{
[K in keyof ${Input}]: ${Input}[K] | null
}`
const validator = compile(Output) // const validator: TValidator<{
// x: number | null;
// y: number | null;
// z: number | null;
// }>Transform TypeScript to JSON Schema
Use the parse function to transform TypeScript into JSON Schema.
import { parse, type Static } from 'typedriver'
const Vector = parse(`{
x: number
y: number
z: number
}`)
type Vector = Static<typeof Vector> // type Vector = {
// x: number,
// y: number,
// z: number
// }
console.log(Vector) // prints: {
// type: 'object',
// required: ['x', 'y', 'z'],
// properties: {
// x: { type: 'number'},
// y: { type: 'number'},
// z: { type: 'number'}
// }
// }TypeScript | JSON Schema | Standard Schema
TypeDriver has unified type inference for TypeScript, JSON Schema, and Standard Schema. Use the Static<T> type to derive a static TypeScript type from any runtime type definition.
import { type Static } from 'typedriver'
type T = Static<`{ value: number }`> // type T = {
// value: number
// }import { type Static } from 'typedriver'
type T = Static<{ // type T = {
type: 'object', // value: number
required: ['value'], // }
properties: {
value: {
type: 'number'
}
}
}>import { type Static } from 'typedriver'
const T = z.object({
value: z.number()
})
type T = Static<typeof T> // type T = {
// value: number
// }TypeDriver uses JSON Schema to represent TypeScript at runtime. Compiled validators include a toJsonSchema() function that returns the internal JSON Schema representation.
import compile from 'typedriver'
const validator = compile(`{ x: number }`)
validator.isJsonSchema() // Returns true if the compiled type
// supports JSON Schema transform. This
// is true for TypeScript, JSON Schema,
// and library implementations of
// Standard JSON Schema.
validator.toJsonSchema() // Returns JSON Schema or an empty
// schema {} if not supported.The original type used for compilation can also be retrieved via:
validator.toType() // Returns the original type or
// schema used for compilation.Typed Function | Express Router
TypeDriver is designed for framework integration. The following is a starter script for a runtime and static type-safe function that is able to accept any TypeScript, JSON Schema or Standard Schema definition.
import compile, { type Static } from 'typedriver'
// Callback
export type TCallback<
Input extends unknown,
Output extends unknown
> = (value: Input) => Output
// Options
export type TOptions<
Input extends unknown = unknown,
Output extends unknown = unknown
> = {
input?: Input,
output?: Output
}
// TypedFunction
export function TypedFunction<const Options extends TOptions,
Input extends unknown = Static<Options['input']>,
Output extends unknown = Static<Options['output']>,
Callback extends TCallback<Input, Output> = TCallback<Input, Output>
>(options: Options, callback: Callback): Callback {
const input = compile(options['input'])
const output = compile(options['output'])
return (
(value: unknown) => output.parse(callback(input.parse(value) as never))
) as never
}
// Example
const add = TypedFunction({
input: `{ a: number, b: number }`,
output: `number`
}, ({ a, b }) => a + b)
const sum = add({ a: 1, b: 2 }) // const value = 3 TypeDriver is built for performance and to be as lean as possible while hosting a TypeScript DSL engine and JSON Schema 2020-12 validation compiler. The following are high level metrics for the library.
The following table shows library throughput with and without TypeDriver acceleration.
$ deno task benchPerformance Metrics
┌────────────┬────────────┬─────────────┬────────────────┬───────────────┬──────────────┐
│ (idx) │ iterations │ accelerated │ standard (...) │ compile (...) │ performance │
├────────────┼────────────┼─────────────┼────────────────┼───────────────┼──────────────┤
│ typescript │ 16000000 │ true │ " 28 ms" │ " 29 ms" │ " 0.97 ×" │
│ jsonschema │ 16000000 │ true │ " 30 ms" │ " 30 ms" │ " 1.02 ×" │
│ zod │ 16000000 │ true │ " 612 ms" │ " 29 ms" │ " 21.10 ×" │
│ arktype │ 16000000 │ true │ " 530 ms" │ " 27 ms" │ " 19.32 ×" │
│ valibot │ 16000000 │ true │ " 4103 ms" │ " 30 ms" │ " 134.98 ×" │
└────────────┴────────────┴─────────────┴────────────────┴───────────────┴──────────────┘
Last Run: Tue Jun 23 2026TypeDriver compresses to approximately 50kb gzipped.
$ deno task metricsCompression Metrics
┌───────┬─────────────────────────┬─────────────┬─────────────┬────────────┐
│ (idx) │ path │ bundled │ minified │ gzipped │
├───────┼─────────────────────────┼─────────────┼─────────────┼────────────┤
│ 0 │ "./task/metrics/all.ts" │ "519.58 KB" │ "266.53 KB" │ "51.99 KB" │
└───────┴─────────────────────────┴─────────────┴─────────────┴────────────┘TypeDriver is open to community contribution. Please ensure you submit an issue before submitting a pull request. This project prefers open community discussion before accepting new features.