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

TypeScript项目中Yup验证when方法is条件触发TS2769错误如何解决?

问题:Yup表单验证中使用when函数触发TS2769类型错误

我正在开发一个TypeScript项目,使用Yup进行表单验证。在使用when函数配置is条件时,触发了类型相关的TS2769错误,无法自行解决。相关代码及错误信息如下:

类型定义

export type TClubFormData = {
  title: string;
  description: string;
  info: string;
  city: string;
  address: string;
  phone: string;
  picture: File | null;
  pictureUrl: string;
  latitudeMap: string;
  longitudeMap: string;
  openingTime: string;
  closingTime: string;
};

初始值

const initialValues: TClubFormData = {
    title: (club && club.title) || '',
    description: (club && club.description) || '',
    info: (club && club.info) || '',
    address: (club && club.address) || '',
    city: (club && club.city) || '',
    phone: (club && club.phone) || '',
    picture: null,
    pictureUrl: (club && club.picture) || '',
    latitudeMap: (club && club.latitudeMap) || '',
    longitudeMap: (club && club.longitudeMap) || '',
    openingTime: (club && club.openingTime) || '00:00',
    closingTime: (club && club.closingTime) || '00:00',
  };

验证Schema

export const CreateAndEditClubFormSchema = Yup.object().shape({
  title: Yup.string().required('Անվանումը պարտադիր է'),
  description: Yup.string().required('Նկարագիրը պարտադիր է'),
  info: Yup.string(),
  city: Yup.string().required('Քաղաքը պարտադիր է'),
  address: Yup.string().required('Հասցեն պարտադիր է'),
  phone: Yup.string(),
  picture: Yup.mixed().when('pictureUrl', {
    is: (pictureUrl: string) => !pictureUrl, // 错误发生在这里
    then: Yup.mixed().nullable().required('Նկարը պարտադիր է'),
    otherwise: Yup.mixed().nullable(),
  }),
  latitudeMap: Yup.string().matches(
    /^(\+|-)?((\d((\.)|\.\d{1,6})?)|(0*?[0-8]\d((\.)|\.\d{1,6})?)|(0*?90((\.)|\.0{1,6})?))$/,
    'Սխալ կորդինատային լայնություն'
  ),
  longitudeMap: Yup.string().matches(
    /^(\+|-)?((\d((\.)|\.\d{1,6})?)|(0*?\d\d((\.)|\.\d{1,6})?)|(0*?1[0-7]\d((\.)|\.\d{1,6})?)|(0*?180((\.)|\.0{1,6})?))$/,
    'Սխալ կորդինատային երկայնություն'
  ),
  openingTime: Yup.string().required('Opening time is required'),
  closingTime: Yup.string().required('Closing time is required'),
});

错误信息

TS2769: No overload matches this call.
Overload  1  of  4 ,
(keys: string | string[], builder: ConditionBuilder<MixedSchema<AnyPresentValue | undefined, AnyObject, undefined, "">>): MixedSchema<...>
, gave the following error.
Argument of type
{     is: (pictureUrl: string) => boolean;     then: Yup.MixedSchema<AnyPresentValue, Yup.AnyObject, undefined, "">;     otherwise: Yup.MixedSchema<AnyPresentValue | null | undefined, Yup.AnyObject, undefined, "">; }
is not assignable to parameter of type
ConditionBuilder<MixedSchema<AnyPresentValue | undefined, AnyObject, undefined, "">>
Object literal may only specify known properties, and  is  does not exist in type
ConditionBuilder<MixedSchema<AnyPresentValue | undefined, AnyObject, undefined, "">>

解决方案

方案1:改用函数式ConditionBuilder写法

Yup在TypeScript环境下,对象式的when配置容易触发类型推断问题,改用函数式写法可直接规避:

picture: Yup.mixed().when('pictureUrl', (pictureUrl, schema) => {
  return !pictureUrl 
    ? schema.nullable().required('Նկարը պարտադիր է') 
    : schema.nullable();
}),

这种写法直接接收依赖字段值和当前schema实例,通过条件返回对应验证规则,TypeScript能正确推断类型。

方案2:为字段指定明确类型(类型断言)

若坚持使用对象式写法,可通过类型断言明确字段类型,同时添加类型守卫辅助TypeScript识别:

picture: Yup.mixed<File | null>().when('pictureUrl', {
  is: (pictureUrl: unknown): pictureUrl is string => typeof pictureUrl === 'string' && !pictureUrl,
  then: Yup.mixed<File | null>().nullable().required('Նկարը պարտադիր է'),
  otherwise: Yup.mixed<File | null>().nullable(),
}),

通过mixed<File | null>明确字段类型,is条件中的类型守卫确保TypeScript正确识别pictureUrl的类型。

方案3:升级Yup版本

部分旧版Yup的TypeScript类型定义存在缺陷,升级到最新稳定版(如yup@1.x)可能修复该问题:

npm install yup@latest
# 或
yarn add yup@latest

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 03:29:58