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

Yup嵌套对象验证:允许空对象但非空值需非空校验

Yup验证placements对象的正确方案

待验证的对象结构

placements: {
  3: {},
  5: {},
  6: {0: 'D17'},
  7: {},
  8: {},
  9: {},
  10: {},
  11: {},
}

验证规则

  • 子对象允许为空
  • 若子对象包含键值对,所有字符串值必须非空(长度>0)
  • 整个placements对象至少包含一个有效子对象(即带有非空值的子对象)

原代码问题分析

原代码仅检查了是否存在非空值,但未处理子对象包含空字符串值的情况(比如{0: ""}),这种不符合规则的场景会被原代码忽略,导致验证失效。

正确验证代码

placements: Yup.object()
  .required("必须选择位置")
  // 验证所有子对象:要么为空,要么所有值都非空
  .test(
    "all-placements-valid",
    "所有已填写的位置值不能为空",
    (placements) => {
      return Object.values(placements).every(placement => {
        const values = Object.values(placement);
        // 子对象为空,或所有值都是非空字符串
        return values.length === 0 || values.every(val => typeof val === 'string' && val.length > 0);
      });
    }
  )
  // 验证至少存在一个有效位置
  .test(
    "at-least-one-valid",
    "必须选择至少一个位置",
    (placements) => {
      return Object.values(placements).some(placement => {
        return Object.values(placement).some(val => typeof val === 'string' && val.length > 0);
      });
    }
  )

代码说明

  1. required确保placements对象本身不可为空(null/undefined)
  2. 第一个test遍历所有子对象:若子对象有值,必须所有值都是非空字符串;子对象为空则直接通过
  3. 第二个test确保至少有一个子对象包含有效非空值,满足“至少选一个位置”的要求

若需要忽略首尾空格的空值(比如" "),可以把val.length > 0替换为val.trim().length > 0

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 21:33:01