安装
$ npm install typebox
用法
import Type from 'typebox'
const T = Type.Object({ // const T = {
x: Type.Number(), // type: 'object',
y: Type.Number(), // properties: {
z: Type.Number() // x: { type: 'number' },
}) // y: { type: 'number' },
// z: { type: 'number' }
// },
// required: ['x', 'y', 'z']
// }
type T = Type.Static<typeof T> // type T = {
// x: number,
// y: number,
// z: number
// }
概述
TypeBox 是一个运行时类型系统,它创建内存中的 JSON Schema 对象,并将其推断为 TypeScript 类型。该库生成的模式旨在匹配 TypeScript 编译器的静态类型检查规则。TypeBox 提供了一种统一类型,该类型可由 TypeScript 进行静态检查,并可使用标准 JSON Schema 验证进行运行时检查。
该库旨在允许 JSON Schema 以类似于 TypeScript 类型系统中类型组合的方式进行组合。它可以用作构建复杂模式的简单工具,或集成到 REST 和 RPC 服务中,以帮助验证通过线路接收的数据。
许可证:MIT
目录
类型
TypeBox 类型是 JSON Schema 片段,可组合成更复杂的类型。该库提供了一组用于构建符合 JSON Schema 规范的图式的类型,以及一组用于建模 JavaScript 语言原生构造的扩展类型。TypeBox 生成的图式可以直接传递给任何符合 JSON Schema 规范的验证器。
示例
以下代码创建一个 User 类型,并通过 Static 进行推断。
import Type from 'typebox'
// Type
const User = Type.Object({ // const User = {
id: Type.String(), // type: 'object',
name: Type.String(), // properties: {
email: Type.String({ format: 'email' }) // id: { type: 'string' },
}) // name: { type: 'string' },
// email: {
// type: 'string',
// format: 'email'
// }
// },
// required: [
// 'id',
// 'name',
// 'email'
// ]
// }
// Static
type User = Type.Static<typeof User> // type User = {
// id: string,
// name: string,
// email: string
// }
脚本
TypeBox 包含一个运行时 TypeScript 引擎,可将 TypeScript 定义转换为 JSON Schema。该引擎完全类型安全,并支持许多可编程构造,包括 Conditional、Mapped、Indexed、Generics、Distributive Generics 等。
示例
可通过 Visual Studio Marketplace 获取语法高亮支持
import Type from 'typebox'
// Math Module
const Math = Type.Script(`
type Vector4 = { x: number, y: number, z: number, w: number }
type Vector3 = { x: number, y: number, z: number }
type Vector2 = { x: number, y: number }
`)
// Graphics Module
const Graphics = Type.Script(Math, `
type Vertex = {
position: Vector4,
normal: Vector3,
uv: Vector2
}
type Geometry = {
vertices: Vertex[],
indices: number[]
}
type Material = {
ambient: Vector4,
diffuse: Vector4,
specular: Vector4
}
type Mesh = {
geometry: Geometry,
material: Material
}
`)
type Mesh = Type.Static<typeof Graphics['Mesh']> // type Mesh = {
// geometry: { ... },
// material: { ... }
// }
Schema
Documentation | Example 1 | Example 2
TypeBox 包含一个高性能的 JIT 编译器,支持从 JSON Schema Draft 3 到 2020-12 的版本。它旨在作为 Ajv 的轻量级工业级替代方案,并提供改进的编译和验证性能。它还提供在 JIT 受限环境(如 Cloudflare Workers)中自动回退到动态验证的功能。
该编译器可通过可选的子模块导入使用。
import Schema from 'typebox/schema'
编译
编译器接受 TypeBox 类型或原生 JSON Schema。
// Type
const VectorA = Schema.Compile(Type.Object({ // const VectorA: Validator<TObject<{
x: Type.Number(), // x: TNumber
y: Type.Number(), // y: TNumber
z: Type.Number() // z: TNumber
})) // }>>
// Schema
const VectorB = Schema.Compile({ // const VectorB: Validator<{
type: 'object', // type: "object";
required: ['x', 'y', 'z'], // required: ["x", "y", "z"];
properties: { // properties: { ... };
x: { type: 'number' }, // }, { ... }>
y: { type: 'number' },
z: { type: 'number' }
}
})
验证
编译后的验证器实例提供了用于检查和解析值的函数。
// Compile
const Vector = Schema.Compile(Type.Script(`{
x: number
y: number
z: number
}`))
// Check
const valid = Vector.Check({ x: 1, y: 0, z: 0 }) // const valid: boolean
// Parse
const result = Vector.Parse({ x: 1, y: 0, z: 0 }) // const result: {
// x: number
// y: number
// z: number
// }
覆盖率
下表展示了 TypeBox 实现的规范覆盖率。
| Spec | 3 | 4 | 6 | 7 | 2019-09 | 2020-12 | v1 |
|---|---|---|---|---|---|---|---|
| additionalItems | ✅ | ✅ | ✅ | ✅ | ✅ | - | - |
| additionalProperties | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| allOf | - | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| anchor | - | - | - | - | ✅ | ✅ | ✅ |
| anyOf | - | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| boolean_schema | - | - | ✅ | ✅ | ✅ | ✅ | ✅ |
| const | - | - | ✅ | ✅ | ✅ | ✅ | ✅ |
| contains | - | - | ✅ | ✅ | ✅ | ✅ | ✅ |
| content | - | - | - | - | ✅ | ✅ | ✅ |
| default | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| dependencies | 17/18 | ✅ | ✅ | ✅ | - | - | - |
| dependentRequired | - | - | - | - | ✅ | ✅ | ✅ |
| dependentSchemas | - | - | - | - | ✅ | ✅ | ✅ |
| dynamicRef | - | - | - | - | - | 38/44 | 19/27 |
| enum | 14/16 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| exclusiveMaximum | - | - | ✅ | ✅ | ✅ | ✅ | ✅ |
| exclusiveMinimum | - | - | ✅ | ✅ | ✅ | ✅ | ✅ |
| if-then-else | - | - | - | ✅ | ✅ | ✅ | ✅ |
| infinite-loop-detection | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| items | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| maxContains | - | - | - | - | ✅ | ✅ | ✅ |
| maximum | 13/14 | 13/14 | ✅ | ✅ | ✅ | ✅ | ✅ |
| maxItems | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| maxLength | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| maxProperties | - | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| minContains | - | - | - | - | ✅ | ✅ | ✅ |
| minimum | 12/13 | 16/17 | ✅ | ✅ | ✅ | ✅ | ✅ |
| minItems | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| minLength | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| minProperties | - | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| multipleOf | - | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| not | - | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| oneOf | - | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| pattern | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| patternProperties | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| prefixItems | - | - | - | - | - | ✅ | ✅ |
| properties | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| propertyNames | - | - | ✅ | ✅ | ✅ | ✅ | ✅ |
| recursiveRef | - | - | - | - | ✅ | - | - |
| ref | 22/27 | 37/45 | 67/70 | 75/78 | 79/81 | 77/79 | 77/79 |
| required | 3/4 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| type | 73/80 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| unevaluatedItems | - | - | - | - | ✅ | ✅ | 70/71 |
| unevaluatedProperties | - | - | - | - | ✅ | ✅ | 128/129 |
| uniqueItems | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
性能
下表展示了使用 AJV8 作为基准,针对各种 JSON Schema 结构的编译性能。
┌──────────────────────┬─────────────┬─────────────┐
│ Compile │ TB1X │ AJV8 │
├──────────────────────┼─────────────┼─────────────┤
│ Boolean │ 39.7K ops/s │ 6.8K ops/s │
│ Number │ 86.2K ops/s │ 7.5K ops/s │
│ String │ 82.6K ops/s │ 8.2K ops/s │
│ Null │ 62K ops/s │ 7.3K ops/s │
│ Literal_String │ 72.1K ops/s │ 5.7K ops/s │
│ Literal_Number │ 72.7K ops/s │ 6.9K ops/s │
│ Literal_Boolean │ 80.9K ops/s │ 7K ops/s │
│ Pattern │ 38.7K ops/s │ 5.7K ops/s │
│ Object_Open │ 16.3K ops/s │ 1.3K ops/s │
│ Object_Close │ 15.7K ops/s │ 952 ops/s │
│ Object_Vector3 │ 40.2K ops/s │ 3.2K ops/s │
│ Object_Basis3 │ 16.1K ops/s │ 834 ops/s │
│ Intersect_And │ 45.7K ops/s │ 3.5K ops/s │
│ Intersect_Structural │ 21K ops/s │ 1.6K ops/s │
│ Union_Or │ 45.1K ops/s │ 3.4K ops/s │
│ Union_Structural │ 27.6K ops/s │ 2K ops/s │
│ Tuple_Values │ 14.7K ops/s │ 2K ops/s │
│ Tuple_Objects │ 3.7K ops/s │ 380 ops/s │
│ Array_Numbers_4 │ 73.6K ops/s │ 4.3K ops/s │
│ Array_Numbers_8 │ 50.9K ops/s │ 3.8K ops/s │
│ Array_Numbers_16 │ 85K ops/s │ 3.9K ops/s │
│ Array_Objects_Open │ 18.9K ops/s │ 789 ops/s │
│ Array_Objects_Close │ 17.9K ops/s │ 909 ops/s │
└──────────────────────┴─────────────┴─────────────┘
下表展示了使用 AJV8 作为比较基准时,各种 JSON Schema 结构的验证性能。
┌──────────────────────┬──────────────┬──────────────┐
│ Validate │ TB1X │ AJV8 │
├──────────────────────┼──────────────┼──────────────┤
│ Boolean │ 192.2M ops/s │ 189.5M ops/s │
│ Number │ 112.4M ops/s │ 61M ops/s │
│ String │ 113.7M ops/s │ 64.1M ops/s │
│ Null │ 112.8M ops/s │ 64.9M ops/s │
│ Literal_String │ 108M ops/s │ 62.9M ops/s │
│ Literal_Number │ 113.5M ops/s │ 63.2M ops/s │
│ Literal_Boolean │ 109.2M ops/s │ 64.1M ops/s │
│ Pattern │ 26.5M ops/s │ 22.4M ops/s │
│ Object_Open │ 78M ops/s │ 47.2M ops/s │
│ Object_Close │ 38.6M ops/s │ 27.6M ops/s │
│ Object_Vector3 │ 91M ops/s │ 51.3M ops/s │
│ Object_Basis3 │ 41.1M ops/s │ 27.4M ops/s │
│ Intersect_And │ 107.6M ops/s │ 59.9M ops/s │
│ Intersect_Structural │ 83.6M ops/s │ 46.3M ops/s │
│ Union_Or │ 95M ops/s │ 7.9M ops/s │
│ Union_Structural │ 84.5M ops/s │ 52.3M ops/s │
│ Tuple_Values │ 74.7M ops/s │ 53M ops/s │
│ Tuple_Objects │ 32.9M ops/s │ 22.3M ops/s │
│ Array_Numbers_4 │ 93.3M ops/s │ 55.1M ops/s │
│ Array_Numbers_8 │ 90.3M ops/s │ 50.8M ops/s │
│ Array_Numbers_16 │ 76.8M ops/s │ 39.6M ops/s │
│ Array_Objects_Open │ 28.7M ops/s │ 20.4M ops/s │
│ Array_Objects_Close │ 10.3M ops/s │ 10.8M ops/s │
└──────────────────────┴──────────────┴──────────────┘
版本
TypeBox 提供两个不同的版本,涵盖两代 TypeScript 编译器。
| TypeBox | TypeScript | 描述 |
|---|---|---|
| 1.x | 6.0 - 7.0+ | 最新。 针对 TypeScript 7 原生编译器开发。提供高级类型推断和原生 JSON Schema 2020-12 支持。包含对 0.x 类型的向后兼容性。仅支持 ESM。 |
| 0.x | 5.0 - 6.0 | LTS。 针对旧版 TypeScript 开发,并在长期支持(Long Term Support)下积极维护。兼容 ESM 和 CJS。问题应提交至 Sinclair TypeBox 仓库。 |
贡献
TypeBox 欢迎社区贡献。请在提交拉取请求之前确保先提交一个问题。TypeBox 项目在接受新功能之前,倾向于进行开放的社区讨论。