TypeScript项目中Yup定义Date类型schema出现类型不兼容如何解决
问题出现在我们使用Date对象时。Yup自带名为date的自定义方法,我原本以为它可以匹配JavaScript原生的Date对象类型,但实际使用时抛出错误。
// 作为 react-hook-form 中 useForm 的类型使用 export type MySlideSchemaType = { questionField: Date } // 作为 useForm 的 resolver 使用 export const mySlideSchema: yup.SchemaOf<MySlideSchemaType> = yup.object({ questionField: yup.date().required() })
Intellij报错信息:
The types of 'fields.questionField' are incompatible between these types. Type 'RequiredDateSchema<Date, Record<string, any>>' is not assignable to type 'ObjectSchemaOf<Date> | ObjectSchemaOf<Lazy<Date, never>>'. Type 'RequiredDateSchema<Date, Record<string, any>>' is not assignable to type 'ObjectSchemaOf<Lazy<Date, never>>'.
请问我该如何在yup schema中正确实现Date对象类型的定义?
解决方案
这个报错的根因是Yup的类型推导逻辑,SchemaOf会默认尝试将字段类型推导为嵌套的Yup对象Schema,而原生Date是JS内置类型,就出现了类型不匹配的问题。你可以任选以下一种方案解决:
方案1:官方推荐类型推导方式(优先选择)
Yup官方更推荐从Schema反向推导TS类型,不需要手动定义类型再约束Schema,完全避免类型不一致的问题:
// 先定义校验Schema export const mySlideSchema = yup.object({ questionField: yup.date().required() }) // 直接从Schema推导TS类型,直接给react-hook-form的useForm做泛型参数 export type MySlideSchemaType = yup.InferType<typeof mySlideSchema>
这种写法不需要额外做任何类型标注,运行时校验和静态类型提示都会完全符合预期。
方案2:手动指定Date类型泛型
如果你必须先定义TS类型,再约束Schema的结构,可以给yup.date()显式指定泛型匹配原生Date类型:
export type MySlideSchemaType = { questionField: Date } export const mySlideSchema: yup.SchemaOf<MySlideSchemaType> = yup.object({ // 显式指定date schema匹配原生Date类型 questionField: yup.date<Date>().required() })
方案3:Yup v1版本适配
如果你使用的是Yup 1.x版本,SchemaOf已经被废弃,替换为ObjectSchema即可解决类型不兼容问题:
// Yup v1 版本写法 export type MySlideSchemaType = { questionField: Date } export const mySlideSchema: yup.ObjectSchema<MySlideSchemaType> = yup.object({ questionField: yup.date().required() })
以上三种方案都可以解决类型报错的问题,同时运行时会正确校验字段值是否为合法的Date实例。
内容的提问来源于stack exchange,提问作者Kuboczoch
相关产品推荐
相关产品推荐

