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

TypeScript中Yup的InferType将notRequired嵌套字段错误推导为必填项

问题原因

这个问题本质是TypeScript类型规则和Yup类型推导逻辑的共同结果:

  • TypeScript中key: T | undefined和key?: T是两种完全不同的类型:前者要求键必须存在,值可以为undefined;后者才允许完全省略该键。
  • 截止当前最新稳定版Yup,调用嵌套对象schema的.notRequired()/.optional()方法时,类型推导只会给字段值类型加上| undefined,不会自动给对象键添加可选修饰符?,就会出现你遇到的:显式传taxonomy: undefined不报错,但省略字段就报类型错误的现象。2020年官方修复的是基础类型字段的可选推导问题,嵌套对象的可选键修饰符透传问题一直没有完全覆盖。
解决方法

你可以任选以下一种方案修复:

  • 方案1:在定义嵌套子schema时,链式调用.default(undefined),此时Yup的类型推导会自动给对应字段加上可选键修饰符,无需额外处理即可正常省略属性。
    修正后的示例代码:
    import { object, string, InferType } from 'yup';
    
    const taxonomySchema = object({
      code: string().required(),
    }).default(undefined); // 加这一行即可
    
    const platformSchema = object({
      name: string().required(),
      taxonomy: taxonomySchema.notRequired(),
    });
    
    type Platform = InferType<typeof platformSchema>;
    
    const platform: Platform = {
      name: 'Foo',
    }; // 此时无类型报错
    
  • 方案2:写一个通用工具类型修正Yup的推导结果,自动把值包含undefined的字段转为可选键,不需要修改原有schema定义:
    type FixYupOptional<T> = {
      [K in keyof T as undefined extends T[K] ? never : K]: T[K];
    } & {
      [K in keyof T as undefined extends T[K] ? K : never]?: T[K];
    };
    
    // 使用时包裹InferType的结果即可
    type Platform = FixYupOptional<InferType<typeof platformSchema>>;
    
  • 方案3:检查项目中Yup的导入方式,不要混用import * as yup from 'yup'和单独解构导入import { object } from 'yup'两种写法,统一导入方式可以避免部分类型引用不一致导致的推导异常。如果仍有问题,可以在tsconfig中暂时关闭exactOptionalPropertyTypes配置,此时key: T | undefined的类型也允许省略键。

注意:不要为了绕过报错直接给字段加.nullable(),这会允许字段值为null,和你预期的「可选、不传即为undefined」的校验逻辑不一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 03:51:19