Lzh on GitHub

学习了如何创建模式,现在我们来看看如何使用它来验证未知数据并使其类型安全。有三种不同的方法可以实现这一点。

解析并抛出(Parse and throw)

如果输入与模式不匹配,parse 方法将抛出 ValiError。因此,你应该使用 try/catch 块来捕获错误。如果输入与模式匹配,它就是有效的,并且将返回具有正确 TypeScript 类型的模式输出。

import * as v from 'valibot';

try {
  const EmailSchema = v.pipe(v.string(), v.email());
  const email = v.parse(EmailSchema, 'jane@example.com');

  // 处理可能发生的错误
} catch (error) {
  console.log(error);
}

解析并返回(Parse and return)

如果你希望返回问题而不是抛出错误,可以使用 safeParse。返回的值会包含 .success 属性,如果输入有效,该属性为 true;否则为 false

如果输入有效,你可以使用 .output 来获取模式验证的输出。否则,如果输入无效,可以通过 .issues 访问找到的问题。

import * as v from 'valibot';

const EmailSchema = v.pipe(v.string(), v.email());

const result = v.safeParse(EmailSchema, 'jane@example.com');

if (result.success) {
  const email = result.output;
} else {
  console.log(result.issues);
}

类型守卫(Type guards)

另一种在特定情况下可能很有用的验证数据的方法是使用类型守卫。你可以使用带有 is 方法的类型谓词,或者使用带有 assert 方法的断言函数。

如果使用类型守卫,将无法访问验证的问题。此外,转换(transformations)不会生效,并且对象的未知键不会被移除。因此,这种方法不像前两种方法那样安全和强大。另外,由于 TypeScript 的限制,它目前只能用于同步模式。

import * as v from 'valibot';

const EmailSchema = v.pipe(v.string(), v.email());

const data: unknown = 'jane@example.com';

if (v.is(EmailSchema, data)) {
  const email = data; // string
}

配置(Configuration)

默认情况下,Valibot 会在验证过程中详尽地收集每个问题,以便为你提供关于输入为何与模式不匹配的详细反馈。如果你的用例不需要这个,你可以通过 abortEarlyabortPipeEarly 来控制此行为,以提高验证性能。

中止验证

如果你将 abortEarly 设置为 true,数据验证将在找到第一个问题时立即中止。如果你只想知道某些数据是否与模式匹配,而不关心具体细节,这可以提高性能。

import * as v from 'valibot';

try {
  const ProfileSchema = v.object({
    name: v.string(),
    bio: v.string(),
  });
  const profile = v.parse(
    ProfileSchema,
    { name: 'Jane', bio: '' },
    { abortEarly: true }
  );

  // 处理可能发生的错误
} catch (error) {
  console.log(error);
}

中止管道

如果你只将 abortPipeEarly 设置为 true,则管道内的验证将在找到第一个问题后中止。例如,如果你在验证表单时只想显示第一个字段的错误,可以使用此选项来提高性能。

import * as v from 'valibot';

try {
  const EmailSchema = v.pipe(v.string(), v.email(), v.endsWith('@example.com'));
  const email = v.parse(EmailSchema, 'jane@example.com', {
    abortPipeEarly: true,
  });

  // 处理可能发生的错误
} catch (error) {
  console.log(error);
}