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

使用Yup .required()时TypeScript未正确推断必填字段类型问题

解决Yup Schema中TypeScript类型推断将必填字段识别为可选的问题

问题场景

我用Yup构建营销活动表单的校验Schema,其中sellers字段是{id: number; label: string}类型的对象数组。但TypeScript推断时,会把数组中对象的id和label识别为可选类型,导致表单类型错误。

我的Yup Schema代码

const validationSchema = yup.object().shape({
    sellers: yup
        .array()
        .of(
            yup.object().shape({
                id: yup.number().required().defined(),
                label: yup.string().defined().required(),
            }),
        )
        .required(),
});

期望的TypeScript类型

{
    sellers: {
        id: number;
        label: string;
    }[];
}

实际推断的TypeScript类型

{
    sellers: {
        id?: number | undefined;
        label?: string | undefined;
    }[];
}

使用环境:TypeScript 5.2.2、Yup 1.3.2,原本以为.required()和.defined()会让TS识别为必填,但没生效,求解决方法。

解决方案

方法1:手动定义目标类型并断言

先明确你需要的类型,再通过类型断言让TS认可Schema的推断结果:

// 手动定义表单值的目标类型
type FormValues = {
  sellers: {
    id: number;
    label: string;
  }[];
};

// 给Schema添加类型断言,强制TS使用定义好的类型
const validationSchema = yup.object().shape({
    sellers: yup
        .array()
        .of(
            yup.object().shape({
                id: yup.number().required().defined(),
                label: yup.string().required().defined(),
            }),
        )
        .required(),
}) as yup.SchemaOf<FormValues>;

方法2:用Yup的InferType结合类型工具修正

如果不想完全手动写类型,可以先获取Yup自动推断的类型,再用TS工具类型把可选字段转为必填:

import { InferType } from 'yup';

const validationSchema = yup.object().shape({
    sellers: yup
        .array()
        .of(
            yup.object().shape({
                id: yup.number().required().defined(),
                label: yup.string().required().defined(),
            }),
        )
        .required(),
});

// 定义工具类型:把对象的所有可选字段转为必填
type RequiredFields<T> = { [K in keyof T]-?: T[K] };

// 修正推断出的类型:将数组里的对象转为全必填
type FormValues = {
  sellers: RequiredFields<InferType<typeof validationSchema>['sellers'][number]>[];
};

方法3:改用strictObject优化类型推断

在Yup 1.x版本中,yup.object()默认允许额外字段,可能干扰TS的类型推断。改用yup.strictObject()可以更严格地约束对象结构,帮助TS更准确识别必填字段:

const validationSchema = yup.object().shape({
    sellers: yup
        .array()
        .of(
            yup.strictObject().shape({
                id: yup.number().required().defined(),
                label: yup.string().required().defined(),
            }),
        )
        .required(),
});

内容的提问来源于stack exchange,提问作者Mehmet Emre Ast

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 15:32:36