TypeBox格式验证失效及Strict模式不生效问题求助
解决方案:TypeBox 严格校验与邮箱格式验证问题
1. Type.Strict() 严格校验不生效
TypeBox 的 Type.Strict() 仅用于标记 schema 为严格模式,但内置的 TypeCheck 工具默认允许未知属性。要实现类似 Zod 的严格校验,需在创建校验器时显式禁用未知属性:
代码示例
import { Type, TypeCheck } from '@sinclair/typebox'; // 定义严格 schema const UserSchema = Type.Strict(Type.Object({ name: Type.String(), age: Type.Number() })); // 创建启用严格校验的校验器 const checkUser = TypeCheck.Create(UserSchema, { allowUnknown: false }); // 测试:带额外属性的对象会校验失败 const invalidUser = { name: 'Alice', age: 30, extra: 'foo' }; console.log(checkUser(invalidUser)); // false console.log(checkUser.Errors(invalidUser)); // 提示存在未知属性
如果使用 AJV 作为校验器,需开启 strict: true 或配置 strictSchema: true 来启用严格校验:
import Ajv from 'ajv'; import { Type } from '@sinclair/typebox'; const ajv = new Ajv({ strict: true }); const validate = ajv.compile(UserSchema);
2. 邮箱格式校验提示“Unknown format 'email'”
TypeBox 本身不内置格式校验逻辑,官方文档提到的“无需 AJV”仅针对基础类型校验。要支持邮箱等格式验证,有两种方案:
方案一:使用 AJV + ajv-formats
安装依赖:
npm install ajv ajv-formats
配置并使用:
import Ajv from 'ajv'; import addFormats from 'ajv-formats'; import { Type } from '@sinclair/typebox'; // 创建 AJV 实例并添加格式支持 const ajv = new Ajv(); addFormats(ajv); // 默认包含 email、url 等常见格式 // 定义带邮箱格式的 schema const UserSchema = Type.Object({ email: Type.String({ format: 'email' }) }); const validate = ajv.compile(UserSchema); // 测试:合法邮箱会通过校验 const validUser = { email: 'test@example.com' }; console.log(validate(validUser)); // true // 非法邮箱会失败 const invalidUser = { email: 'invalid-email' }; console.log(validate(invalidUser)); // false console.log(validate.errors); // 提示格式不符合要求
方案二:扩展 TypeBox 内置 TypeCheck 的格式验证
如果不想依赖 AJV,可以自定义格式验证函数并注册到 TypeBox:
import { Type, TypeCheck, FormatRegistry } from '@sinclair/typebox'; // 注册邮箱格式验证 FormatRegistry.Set('email', (value: string) => { // 使用简单的邮箱正则(可根据需求替换更严谨的规则) const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return emailRegex.test(value); }); // 定义带邮箱格式的 schema const UserSchema = Type.Object({ email: Type.String({ format: 'email' }) }); // 创建校验器 const checkUser = TypeCheck.Create(UserSchema); // 测试验证结果 console.log(checkUser({ email: 'test@example.com' })); // true console.log(checkUser({ email: 'invalid-email' })); // false
常见疑问解答
- 为什么官方说无需 AJV 但验证不生效?
TypeBox 内置的TypeCheck仅支持基础类型(string、number、boolean 等)和结构校验,不包含格式、自定义规则等复杂校验逻辑。这类场景需要依赖 AJV 或自定义扩展。 - 使用 ajv-formats-draft2019 注意事项?
如果使用 draft2019 版本的格式,需指定格式版本:import addFormats from 'ajv-formats-draft2019'; addFormats(ajv, { mode: 'draft2019' });
内容的提问来源于stack exchange,提问作者Mr X
相关产品推荐
相关产品推荐

