2 回答
TA贡献1890条经验 获得超9个赞
我设法通过扩展T到然后定义保留传入类型any[]的结果来弄清楚:validatedFields as T
const fieldValidator = <
T extends any[]
>(
fields: T,
): { validatedFields: T; errors: number } => {
try {
if (!fields || fields.length < 0) throw new Error("You must supply an array of fields!");
let errorCount: number = 0;
const validatedFields = fields.map(field => {
let errors = "";
const { type, value, required }: Pick<BaseFieldProps, "type" | "value" | "required"> = field;
if ((!value && required) || ((value && value.length < 0) && required)) {
errors = "Required.";
} else if (
type === "email" &&
!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(value)
) {
errors = "Invalid email.";
}
if (errors) errorCount += 1;
return { ...field, errors };
}) as T;
return { validatedFields, errors: errorCount };
} catch (err) {
throw String(err);
}
};
TA贡献1820条经验 获得超2个赞
这是你要找的吗?
type EssentialField = { type: string; value: string; required?: boolean }[];
打字稿使用鸭子打字。
type FieldProps = {
className?: string,
disabled?: boolean,
errors?: string,
placeholder?: string,
label: string,
// onChange?: (e: React.ChangeEvent<any>) => void;
name: string,
type: string,
readOnly?: boolean,
required: boolean,
value: string
styles?: object
};
const fields: FieldProps[] = [
{
type: "text",
label: "Username",
name: "username",
errors: "",
value: "",
required: true,
},
{
className: "example",
type: "password",
label:"Passowrd",
name: "password",
errors: "",
value: "",
required: true,
styles: { width: "150px" },
}
];
type EssentialField = { type: string; value: string; required?: boolean }[];
const fieldValidator = (
fields: EssentialField,
): { validatedFields: EssentialField; errors: number } => {
try {
if (!fields || fields.length < 0) throw new Error("You must supply an array of fields!");
let errorCount: number = 0;
const validatedFields = fields.map(field => {
let errors = "";
const { type, value, required } = field;
if ((!value && required) || ((value && value.length < 0) && 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 };
});
return { validatedFields, errors: errorCount };
} catch (err) {
throw String(err);
}
};
const { validatedFields, errors } = fieldValidator(fields)
console.log(validatedFields)
console.log(errors);
这消除了错误,没有使用as any或其他技巧。
编辑:也许你想要这样的东西:
type EssentialField = ({ type: string; value: string; required?: boolean }&{[key: string]: any})[];
// this allow you to do:
validatedFields[0].placeholder; // ...
// or
validatedFields[0].someUnknowProperty; // ...
这是将类型与关联数组 ( {[key: string]: any})) 相交。通常这样访问associativeArray['someKey'],但也可以这样使用associativeArray.someKey。
好处是您的 IDE 应该在自动完成中为您推荐type和字段。required
添加回答
举报