You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Yup校验对象数组并移除校验未通过的无效字段?

问题原因

Yup 的 cast 方法仅负责类型转换、以及根据 stripUnknown 配置移除 schema 未定义的额外字段,不会自动移除 schema 中已定义、但校验规则不通过的字段,这是当前代码没有达到预期效果的核心原因。

实现方案

你可以先全量校验收集所有失败字段的路径,再手动清理对应字段,具体实现代码如下:

// 你的原有 schema 无需修改
const schema = Yup.object().shape({
  id: Yup.string().nullable(false),
  country: Yup.string().trim().nullable(false),
  firstname: Yup.string().trim().nullable(false),
  lastname: Yup.string().trim().nullable(false),
  email: Yup.string().trim().nullable(false).email(),
  phoneNum: Yup.string()
    .trim()
    .test("phone", "", (value) => isPossiblePhoneNumber(`+1${value}`))
});
const schemaArr = Yup.array().of(schema);

// 核心处理逻辑
const processInput = async (input) => {
  let invalidFields = [];
  try {
    // 全量校验收集所有错误,必须开启abortEarly: false
    await schemaArr.validate(input, { abortEarly: false, stripUnknown: true });
  } catch (err) {
    // 提取所有校验失败的字段路径,格式如[0].email、[1].phoneNum
    invalidFields = err.inner.map(e => e.path);
  }

  // 先执行cast移除未知字段
  const castedArr = schemaArr.cast(input, { stripUnknown: true });

  // 遍历移除每个对象中校验失败的字段
  return castedArr.map((item, index) => {
    const cleaned = { ...item };
    invalidFields.forEach(path => {
      if (path.startsWith(`[${index}].`)) {
        const field = path.split('.')[1];
        delete cleaned[field];
      }
    });
    return cleaned;
  });
};

// 调用示例
const sanitization = await processInput(你的待校验数组);

可选调整

如果你需要的是仅保留所有字段都校验通过的对象,直接过滤掉存在校验失败字段的对象,可在上述返回逻辑前追加过滤规则:

return castedArr.map(/* 上述清理逻辑 */)
  // 仅保留字段数量和schema定义一致的对象,说明无字段被删除
  .filter(item => Object.keys(item).length === Object.keys(schema.fields).length);

内容的提问来源于stack exchange,提问作者MarksCode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 01:15:03