Lzh on GitHub

要使用模式验证对象,你可以使用 objectrecordobject 用于具有特定形状的对象,而 record 用于具有任意数量统一条目的对象。

Object 模式

object 模式用于验证具有特定结构的对象。它的第一个参数用于定义对象的具体结构,每个条目由一个键和一个模式作为值组成,输入的条目会根据这些模式进行验证。

import * as v from 'valibot';

const ObjectSchema = v.object({
  key1: v.string(),
  key2: v.number(),
});

松散与严格对象

默认的 object 模式会移除未知的条目。这意味着那些你没有在第一个参数中定义的条目不会被验证,也不会被添加到输出中。你可以通过使用 looseObjectstrictObject 模式来改变这种行为。

  • looseObject 模式允许未知条目并将其添加到输出中。
  • strictObject 模式禁止未知条目,并对发现的第一个未知条目返回一个问题。

具有特定其余部分的 Object

此外,你还可以使用 objectWithRest 模式来为未知条目定义一个特定模式。未在第一个参数中定义的任何条目都会根据第二个参数的模式进行验证。

import * as v from 'valibot';

const ObjectSchema = v.objectWithRest(
  {
    key1: v.string(),
    key2: v.number(),
  },
  v.null()
);

管道验证

要根据另一个条目验证某个条目的值,你可以用 check 验证操作将你的模式包装在一个管道中。你还可以使用 forward 在出现错误时将问题分配给特定的对象键。

如果你只想验证特定的条目,我们建议使用 partialCheck,因为 check 只有在输入完全类型化时才能执行。

import * as v from 'valibot';

const CalculationSchema = v.pipe(
  v.object({
    a: v.number(),
    b: v.number(),
    sum: v.number(),
  }),
  v.forward(
    v.check(({ a, b, sum }) => a + b === sum, '计算不正确。'),
    ['sum']
  ));

Record 模式

对于具有任意数量统一条目的对象,record 是正确的选择。它的第一个参数验证记录的键,第二个参数验证值。

import * as v from 'valibot';

const RecordSchema = v.record(v.string(), v.number()); // Record<string, number>

特定记录键

除了 string,你还可以使用 customenumliteralpicklistunion 来验证键。

import * as v from 'valibot';

const RecordSchema = v.record(v.picklist(['key1', 'key2']), v.number()); // { key1?: number; key2?: number }

注意:在这种情况下,record 会将所有字面量键标记为可选。如果你想让它们变为必需,可以使用 object 模式和 entriesFromList 工具。

import * as v from 'valibot';

const RecordSchema = v.object(v.entriesFromList(['key1', 'key2'], v.number())); // { key1: number; key2: number }

管道验证

要根据另一个条目验证某个条目的值,你可以用 check 验证操作将你的模式包装在一个管道中。你还可以使用 forward 在出现错误时将问题分配给特定的记录键。

import * as v from 'valibot';

const CalculationSchema = v.pipe(
  v.record(v.picklist(['a', 'b', 'sum']), v.number()),
  v.forward(
    v.check(
      ({ a, b, sum }) => (a || 0) + (b || 0) === (sum || 0),
      '计算不正确。'
    ),
    ['sum']
  ));