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

Yup使用when方法对数组内对象做条件必填校验问题

问题原因

你的条件校验不生效核心有两个问题:

  • when方法默认只会在当前字段所在的同级对象上下文里查找匹配字段,你写的isAgeRequired是和people数组平级的根级字段,和嵌套在数组项里的age字段差了两层上下文,默认路径根本匹配不到对应的值
  • 原schema没有显式声明根级的isAgeRequired字段规则,Yup校验时不会正确把该字段纳入跨层级访问的上下文里
修正方案

两种写法都可以实现需求,选一种即可:

写法1:相对路径引用(简洁直观)

Yup的when支持相对路径写法,用..表示向上一级上下文查找,从数组项的person对象到根对象需要向上找两层,所以路径写../../isAgeRequired即可,同时补全根字段的类型定义:

import { object, array, string, number, boolean } from 'yup';

const validator = object({
  people: array(
    object({
      name: string().required(),
      age: number()
        .nullable()
        .when("../../isAgeRequired", {
          is: true,
          // 条件命中时要求age必填,自动排除null/undefined空值
          then: (schema) => schema.required(),
          // 条件不命中时保持可空
          otherwise: (schema) => schema.nullable()
        })
    })
  ),
  // 补全根级字段定义
  isAgeRequired: boolean().required()
});

写法2:上下文判断(兼容性更好,不用记路径)

如果怕相对路径写错,可以直接在when里通过校验上下文拿到根级值判断,适配所有Yup版本:

import { object, array, string, number, boolean } from 'yup';

const validator = object({
  people: array(
    object({
      name: string().required(),
      age: number()
        .nullable()
        .when({
          // 直接从上下文栈取最外层根对象的isAgeRequired值判断
          is: (_, context) => {
            const rootContext = context.from[context.from.length - 1].value;
            return rootContext.isAgeRequired === true;
          },
          then: (schema) => schema.required(),
          otherwise: (schema) => schema.nullable()
        })
    })
  ),
  isAgeRequired: boolean().required()
});
校验效果验证
  • 当isAgeRequired: false时,age为null可以正常通过校验
  • 当isAgeRequired: true时,people数组里所有age为null/undefined的项都会触发必填校验报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 16:48:25