如何为嵌套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() }) });
报错原因及解决说明
- 字段名不匹配:代码中写的
firstName和初始对象中的name字段不一致,会导致验证逻辑无效,需修正字段名。 then的取值错误:Yup的when方法中,then和otherwise需要接收一个函数,该函数接收当前schema并返回修改后的schema,而非直接传入新的schema实例。之前直接写then: Yup.string().required("Required")不符合类型要求,改为(schema) => schema.required('提示文本')即可解决类型报错。- 条件判断优化:原条件
!Boolean(value)可优化为!id || id.trim() === '',更严谨地判断id是否为空(包括空字符串和全空格的情况)。
内容的提问来源于stack exchange,提问作者Sudeep Mishra
相关产品推荐
相关产品推荐

