Lzh on GitHub

当你针对模式验证未知数据时,Valibot 会收集关于每个问题的信息。如果至少存在一个问题,这些问题会以数组形式返回。每个问题都提供详细信息,帮助你或你的用户解决问题。

问题信息

单个问题符合以下 TypeScript 类型定义。

type BaseIssue = {
  // 必需信息
  kind: 'schema' | 'validation' | 'transformation';
  type: string;
  input: unknown;
  expected: string | null;
  received: string;
  message: string;

  // 可选信息
  requirement?: unknown;
  path?: IssuePath;
  issues?: Issues;
  lang?: string;
  abortEarly?: boolean;
  abortPipeEarly?: boolean;
  skipPipe?: boolean;
};

必需信息

每个问题都包含以下必需信息。

Kind

kind 描述了问题的类型。如果输入与数据类型不匹配,例如传入的是数字而不是字符串,kind 的值为 'schema'。在所有其他情况下,原因不是数据类型,而是数据的实际内容。例如,如果一个字符串因不匹配正则表达式而无效,kind 的值为 'validation'

Type

type 描述了执行验证的函数。如果 array 模式函数检测到输入不是一个数组,type 的值为 'array'。如果 minLength 验证函数检测到一个数组过短,type 的值为 'min_length'

Input

input 包含了发现问题的输入数据。对于复杂数据,例如对象,input 包含与其模式不匹配的相应键的值。

Expected

expected 是一个语言中立的字符串,描述了所期望的数据属性。它可用于创建有用的错误信息。如果你的用户不是开发人员,你可以将这些语言中立的符号替换为特定语言的词汇。

Received

received 是一个语言中立的字符串,描述了所接收的数据属性。它可用于创建有用的错误信息。如果你的用户不是开发人员,你可以将这些语言中立的符号替换为特定语言的词汇。

Message

message 包含一个人类可理解的错误信息,可以根据我们的 快速入门国际化 指南进行完全自定义。

可选信息

一些问题包含更多可选信息。

Requirement

requirement 可以包含更多验证信息。例如,如果 minLength 验证函数检测到一个字符串过短,requirement 包含该字符串应有的最小长度。

Path

path 是一个对象数组,描述了问题在复杂数据中的位置。每个路径项都包含以下信息。

路径项的 input 可能与其对应问题的 input 不同。这是因为路径项是由父模式后续添加的,并与其输入相关。子模式的转换不被考虑在内。

type PathItem = {
  type: string;
  origin: 'key' | 'value';
  input: unknown;
  key?: unknown;
  value: unknown;
};

例如,你可以使用以下代码来创建一个点路径。

import * as v from 'valibot';

const dotPath = v.getDotPath(issue);

Issues

issues 目前仅在使用 union 时出现,并包含联合类型中所有模式的问题。

Config

lang 可作为我们 i18n 功能 的一部分,用于定义所需的语言。abortEarlyabortPipeEarly 给你一个关于验证提前中止的信息。你可以在 解析数据 指南中找到更多信息。这些都是你可以自己控制的配置。

格式化

对于像表单验证这样的常见用例,Valibot 包含一些小型内置函数用于格式化问题。然而,一旦你理解了它们的工作原理,你就可以轻松地自己格式化它们,并根据你的用例将其转换成正确的形式。

展平错误

如果你只对每个问题的错误信息感兴趣,以便显示给你的用户,你可以使用 flatten 将问题数组转换为一个扁平对象。下面是一个例子。

import * as v from 'valibot';

const ObjectSchema = v.object({
  foo: v.string('Value of "foo" is missing.'),
  bar: v.object({
    baz: v.string('Value of "bar.baz" is missing.'),
  }),
});

const result = v.safeParse(ObjectSchema, { bar: {} });

if (result.issues) {
  console.log(v.flatten<typeof ObjectSchema>(result.issues));
}

上面代码示例中返回的 result 包含以下问题。

[
  {
    kind: 'schema',
    type: 'string',
    input: undefined,
    expected: 'string',
    received: 'undefined',
    message: 'Value of "foo" is missing.',
    path: [
      {
        type: 'object',
        origin: 'value',
        input: {
          bar: {},
        },
        key: 'foo',
        value: undefined,
      },
    ],
  },
  {
    kind: 'schema',
    type: 'string',
    input: undefined,
    expected: 'string',
    received: 'undefined',
    message: 'Value of "bar.baz" is missing.',
    path: [
      {
        type: 'object',
        origin: 'value',
        input: {
          bar: {},
        },
        key: 'bar',
        value: {},
      },
      {
        type: 'object',
        origin: 'value',
        input: {},
        key: 'baz',
        value: undefined,
      },
    ],
  },
];

然而,在 flatten 的帮助下,这些问题被转换成了以下对象。

{
  nested: {
    foo: ['Value of "foo" is missing.'],
    'bar.baz': ['Value of "bar.baz" is missing.'],
  },
};