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

React表单验证Schema类型不兼容:如何解决TypeScript报错?

解决Yup与React Hook Forms结合的TypeScript类型不兼容问题

问题场景

定义的FORM接口:

interface FORM<P> {
  onSubmit: (d: P) => void;
  schema?: yup.SchemaOf<P>;
}

onSubmit函数:

const onSubmit = (d: { firstName: string; lastName: string }) => {
  console.log(d);
};

Yup schema定义:

const schema = yup.object({
  firstName: yup.string().required('name'),
  lastName: yup.string(),
});

传入Test组件时:

<Test
  onSubmit={onSubmit}
  schema={schema}
>

出现TypeScript错误:

TS2322: Type 'OptionalObjectSchema<{ firstName: RequiredStringSchema<string | undefined, AnyObject>; lastName: StringSchema<string | undefined, AnyObject, string | undefined>; }, AnyObject, TypeOfShape<...>>' is not assignable to type 'ObjectSchema<{ firstName: BaseSchema<Maybe, AnyObject, string>; lastName: BaseSchema<Maybe, AnyObject, string>; }, AnyObject, TypeOfShape<...>, AssertsShape<...>>'.
The types of 'fields.lastName.__outputType' are incompatible between these types.
Type 'string | undefined' is not assignable to type 'string'.
Type 'undefined' is not assignable to type 'string'.

错误原因

核心矛盾是类型不匹配:

  • onSubmit的参数要求lastName为必填string
  • 但schema中lastName仅声明为yup.string(),未添加.required()约束,Yup推导的输出类型里lastName是string | undefined
  • 两者类型冲突,触发TypeScript检查报错

解决方法

方法1:让schema与onSubmit参数严格匹配

根据业务需求二选一:

情况A:允许lastName为可选值

修改onSubmit的参数类型,对齐schema的输出:

const onSubmit = (d: { firstName: string; lastName?: string }) => {
  console.log(d);
};

情况B:要求lastName为必填值

给schema的lastName添加必填约束:

const schema = yup.object({
  firstName: yup.string().required('name'),
  lastName: yup.string().required('last name is required'),
});

方法2:显式指定FORM接口的泛型参数

在使用Test组件时,明确声明泛型类型,引导TypeScript正确匹配:

// 允许lastName可选的场景
<Test<{ firstName: string; lastName?: string }>
  onSubmit={onSubmit}
  schema={schema}
>

// 要求lastName必填的场景(需同步修改schema添加.required())
<Test<{ firstName: string; lastName: string }>
  onSubmit={onSubmit}
  schema={schema}
>

方法3:调整FORM接口的类型约束(适配灵活场景)

如果需要接口兼容可选字段的schema,可以放宽schema的类型限制:

import { OptionalObjectSchema, SchemaOf } from 'yup';

interface FORM<P> {
  onSubmit: (d: P) => void;
  schema?: SchemaOf<P> | OptionalObjectSchema<Partial<P>>;
}

这种方式适合多场景兼容需求,但优先推荐前两种方法保证类型严格性。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 08:25:22