我将表单字段表示为对象,这些对象被映射并基于type返回的 React 元素:
import { FieldProps } from "~types";
const fields: FieldProps[] = [
{ type: "text", name: "username", value: "", required: true, ...other props },
{ type: "password", name: "password", value: "", required: true, ...other props },
...etc
]
export default fields;
我遇到的问题是我试图在提交表单后验证字段并检查是否有任何错误value:
handleSubmit = (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
const { validatedFields, errors } = fieldValidator(this.state.fields);
if(errors) {
this.setState({ errors });
return;
}
...etc
}
但是这个可重用的验证函数有一个 ts 错误:
import isEmpty from "lodash.isempty";
/**
* Helper function to validate form fields.
*
* @function
* @param {array} fields - an array containing form fields.
* @returns {object} validated/updated fields and number of errors.
* @throws {error}
*/
const fieldValidator = <
T extends Array<{ type: string; value: string; required?: boolean }>
>(
fields: T,
): { validatedFields: T; errors: number } => {
try {
if (isEmpty(fields)) throw new Error("You must supply an array of form fields to validate!");
let errorCount: number = 0;
// this turns the "validatedFields" array into an { errors: string; type: string; name:
// string; value: string; required?: boolean | undefined;}[] type, when it needs to be "T",
// but "T" won't be inferred as an Array with Object props: type, value, required, value defined within it
const validatedFields = fields.map(field => {
let errors = "";
const { type, value, required } = field;
if ((!value && required) || (isEmpty(value) && required)) {
errors = "Required.";
} else if (
type === "email" &&
!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(field.value)
) {
errors = "Invalid email.";
}
if (errors) errorCount += 1;
return { ...field, errors };
});
有没有一种方法可以推断T为至少需要 4 个(或更多)属性的对象数组,但返回相同类型的数组(仅具有更新的errors属性)?
当年话下
DIEA
相关分类