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

使用DTO创建Yup校验遇类型错误及非校验字段处理咨询

问题:结合DTO创建Yup校验规则时遇到类型错误及字段校验疑问

我尝试结合DTO创建Yup校验规则,目前遇到两个错误:

  • Yup参数无法分配给ObjectShape类型的参数
  • 属性id无法分配给索引签名,number类型无法分配给'Anyschema'类型

移除CargoTypeDetailDto后代码可正常运行。另外咨询:由后端设置的id字段无需校验,除了使用yup.number().notRequired()外是否有其他处理方式?

相关代码

import * as yup from 'yup'
import { CargoTypeDetailDto } from '../../../../../api/planning/open-api/models/CargoTypeDetailDto'

export const cargoTypeDetailDtoSchema = yup.object(<CargoTypeDetailDto>).shape({
  id: yup.number().notRequired(),
  code: yup
    .string()
    .min(1, 'Code can not be below 1')
    .max(10, 'Code can not be above 10')
    .required('Code is required'),
  description: yup
    .string()
    .min(1, 'Description can not be below 1')
    .max(255, 'Description can not be above 255')
    .required('Description is required'),
  priceCode: yup.object().shape({
    code: yup.string().required('Article code is required'),
    name: yup.string().required('Article description is required'),
  }),
  cargoTypeEuCode: yup.object().shape({
    code: yup.string().required('EU code is required'),
    description: yup.string().required('EU description is required'),
  }),
})

DTO定义

import type { CargoTypeEuCodeDto } from './CargoTypeEuCodeDto';
import type { PriceCodeDto } from './PriceCodeDto';

export type CargoTypeDetailDto = {
    id: number;
    code: string;
    description: string;
    priceCode: PriceCodeDto;
    cargoTypeEuCode: CargoTypeEuCodeDto;
};

解决方案

一、修复类型错误

你错误地将TypeScript类型CargoTypeDetailDto当作参数传给了yup.object()——TypeScript类型仅存在于编译阶段,运行时无法被代码读取,所以会触发类型不匹配错误。正确做法是用泛型给Yup Schema指定类型:

修改后的代码:

import * as yup from 'yup'
// 仅导入类型,避免运行时引用
import type { CargoTypeDetailDto } from '../../../../../api/planning/open-api/models/CargoTypeDetailDto'

// 将类型作为泛型参数传入yup.object()
export const cargoTypeDetailDtoSchema = yup.object<CargoTypeDetailDto>().shape({
  id: yup.number().notRequired(),
  code: yup
    .string()
    .min(1, '编码长度不能小于1')
    .max(10, '编码长度不能超过10')
    .required('编码为必填项'),
  description: yup
    .string()
    .min(1, '描述长度不能小于1')
    .max(255, '描述长度不能超过255')
    .required('描述为必填项'),
  priceCode: yup.object().shape({
    code: yup.string().required('商品编码为必填项'),
    name: yup.string().required('商品描述为必填项'),
  }),
  cargoTypeEuCode: yup.object().shape({
    code: yup.string().required('EU编码为必填项'),
    description: yup.string().required('EU描述为必填项'),
  }),
})

核心修改点:

  • 把import { CargoTypeDetailDto }改为import type { CargoTypeDetailDto },明确只导入类型
  • 将<CargoTypeDetailDto>作为泛型参数传给yup.object(),而非当作函数参数传入

二、后端生成的id字段的其他处理方式

除了yup.number().notRequired(),还有以下几种方案:

  • 完全忽略id字段:如果前端提交数据时不需要携带id,直接从Schema中删除id的定义即可。Yup只会校验Schema中声明的字段,未声明的字段默认会被保留(若要移除未声明字段,可添加.stripUnknown(true);若要禁止额外字段,可添加.noUnknown(true))。
  • 使用mixed()跳过类型校验:如果不需要限制id的类型,仅需跳过校验,可写yup.mixed().notRequired(),这样任意类型的id都能通过校验。
  • nullable() + notRequired()组合:如果id可能显式为null或不存在,可写yup.number().nullable().notRequired(),适合后端可能返回null的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 08:15:30