我正在使用其中具有这种类型的Formik:
type FormikErrors<Values> = {
[K in keyof Values]?: Values[K] extends object
? FormikErrors<Values[K]>
: string
};
然后有一个验证函数,基本上看起来像validate<Values>(v: Values) => FormikErrors<Values>
。这个想法是,FormikErrors的键与Values的键匹配,并映射到字符串错误消息,或者如果该字段由嵌套对象表示,则映射到递归FormikErrors对象。
我正在尝试编写一个通用函数来验证必填字段。它只需要使用固定值即可。
export function validateRequired<T, K extends keyof T>(values : T, names: K[]) : FormikErrors<T> {
let errors : FormikErrors<T> = {};
names.forEach((name) => {
if (!values[name]) {
errors[name] = 'This field is required';
}
});
return errors;
}
这是一个错误:
Type error: Type '"This field is required"' is not assignable to type '(T[K] extends object ? FormikErrors<T[K]> : string) | undefined'. TS2322
因为validateRequired返回的对象的值始终是字符串,而不是嵌套的FormikValues。有没有一种方法可以指定值始终是标量,以便可以键入check?
答案 0 :(得分:1)
简单的解决方案是不使用FormikErrors
类型。使用只能包含字符串值的自定义类型:
type RequiredErrors<Values> = {
[K in keyof Values]?: string
};
export function validateRequired<T, K extends keyof T>(values: T, names: K[]): RequiredErrors<T> {
let errors: RequiredErrors<T> = {};
names.forEach((name) => {
if (!values[name]) {
errors[name] = 'This field is required';
}
});
return errors;
}
如果这不是您的选择,那么唯一的解决方案是类型声明。 Typescript无法解析仍具有未解析的泛型类型参数的条件类型,因此无法真正判断string
是否是errors
对象的有效值,但是类型断言可以解决此问题:
export function validateRequired<T, K extends keyof T>(values: T, names: K[]): FormikErrors<T> {
let errors: FormikErrors<T> = {};
names.forEach((name) => {
if (!values[name]) {
errors[name] = 'This field is required' as any;;
}
});
return errors;
}