TypeBox String 类型的 format 参数无效

用例如下:

import { Type } from '@sinclair/typebox';
import { TypeCompiler } from '@sinclair/typebox/compiler';

const schema = Type.Object({
  email: Type.String({ format: 'email' }),
});

const value = {
  email: 'test@example.org',
};

const C = TypeCompiler.Compile(schema);
const valid = C.Check(value);
const errors = C.Errors(value).First();
console.log('isValid:', valid);
console.log(errors);

// 输出结果
// isValid: false
// {
//   type: 49,
//   schema: { format: 'email', type: 'string', [Symbol(TypeBox.Kind)]: 'String' },
//   path: '/email',
//   value: 'test@example.org',
//   message: "Unknown format 'email'",
//   errors: []
// }

原因参见 这个 Issue

TypeBox 默认不包含任何字符串格式验证器,而是需要在使用前进行配置。

import { Type, FormatRegistry } from '@sinclair/typebox'
import { Value } from '@sinclair/typebox/value'

FormatRegistry.Set('email', value => {
  // todo: code here to check the value is email
  return true
}) 

const T = Type.String({ format: 'email' })

const R = Value.Check(T, 'user@domain.com')

TypeBox 项目中有一些示例 ,可以直接拿过来用

  • date-time.ts
  • date.ts
  • email.ts
  • index.ts
  • ipv4.ts
  • ipv6.ts
  • time.ts
  • url.ts
  • uuid.ts

如果验证器使用的 Ajv,参考下面的配置

import { Type } from "@sinclair/typebox";
import addFormats from "ajv-formats";
import Ajv from "ajv";

const ajv = addFormats(new Ajv({}), [
  "date-time",
  "time",
  "date",
  "email",
  "hostname",
  "ipv4",
  "ipv6",
  "uri",
  "uri-reference",
  "uuid",
  "uri-template",
  "json-pointer",
  "relative-json-pointer",
  "regex",
]);

const validate = ajv.compile(
  Type.Object({
    email: Type.String({ format: "email" }),
  })
);

const R = validate({ email: "test@example.org" });