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

如何为嵌套Formik对象编写Yup条件验证Schema并解决类型报错?

问题描述

初始Formik对象结构:

{
  customerDetails: {id: "", name: "", mobileNumber: ""},
  notes: {id: "", text: "", type: ""}
}

需求:编写Yup条件验证Schema,当customerDetails.id存在时,name和mobileNumber非必填;当id不存在时,这两个字段为必填项。

尝试的代码:

const validationSchema = Yup.object().shape({
    customerDetails: Yup.object().shape({
        id: Yup.string(),
        firstName: Yup.string().when('id', {
            is: (value: string) => !Boolean(value),
            then: Yup.string().required("Required")
        }),
    })
})

出现的TypeScript报错:

No overload matches this call.
  Overload 1 of 4, '(keys: string | string[], builder: ConditionBuilder<StringSchema<string, AnyObject, undefined, "">>): StringSchema<string, AnyObject, undefined, "">', gave the following error.
    Argument of type '{ is: (value: string) => boolean; then: Yup.StringSchema<string, Yup.AnyObject, undefined, "">; }' is not assignable to parameter of type 'ConditionBuilder<StringSchema<string, AnyObject, undefined, "">>'.
      Object literal may only specify known properties, and 'is' does not exist in type 'ConditionBuilder<StringSchema<string, AnyObject, undefined, "">>'.
  Overload 2 of 4, '(keys: string | string[], options: ConditionConfig<StringSchema<string, AnyObject, undefined, "">>): StringSchema<string, AnyObject, undefined, "">', gave the following error.
    Type 'StringSchema<string, AnyObject, undefined, "">' is not assignable to type '(schema: StringSchema<string, AnyObject, undefined, "">) => ISchema<any, any, any, any>'.
      Type 'StringSchema<string, AnyObject, undefined, "">' provides no match for the signature '(schema: StringSchema<string, AnyObject, undefined, "">): ISchema<any, any, any, any>'.ts(2769)
index.d.ts(296, 5): The expected type comes from property 'then' which is declared here on type 'ConditionConfig<StringSchema<string, AnyObject, undefined, "">>'
正确实现方案

以下是符合需求的完整Yup验证Schema,同时解决TypeScript类型报错:

import * as Yup from 'yup';

const validationSchema = Yup.object().shape({
  customerDetails: Yup.object().shape({
    id: Yup.string(),
    // 验证name字段
    name: Yup.string().when('id', {
      is: (id: string) => !id || id.trim() === '',
      then: (schema) => schema.required('姓名为必填项'),
      otherwise: (schema) => schema.notRequired()
    }),
    // 验证mobileNumber字段
    mobileNumber: Yup.string().when('id', {
      is: (id: string) => !id || id.trim() === '',
      then: (schema) => schema.required('手机号为必填项'),
      otherwise: (schema) => schema.notRequired()
    })
  }),
  notes: Yup.object().shape({
    id: Yup.string(),
    text: Yup.string(),
    type: Yup.string()
  })
});
报错原因及解决说明
  1. 字段名不匹配:代码中写的firstName和初始对象中的name字段不一致,会导致验证逻辑无效,需修正字段名。
  2. then的取值错误:Yup的when方法中,then和otherwise需要接收一个函数,该函数接收当前schema并返回修改后的schema,而非直接传入新的schema实例。之前直接写then: Yup.string().required("Required")不符合类型要求,改为(schema) => schema.required('提示文本')即可解决类型报错。
  3. 条件判断优化:原条件!Boolean(value)可优化为!id || id.trim() === '',更严谨地判断id是否为空(包括空字符串和全空格的情况)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 03:48:19