Careeroza
Real World Example
Form State From a Model
Form libraries like React Hook Form and Formik derive the value, error and touched types of a form from one model type. A mapped type generates all of them, so adding a field to the model updates the form automatically.
Example
type CheckoutForm = { fullName: string; phone: string; pincode: string; saveAddress: boolean };
type FormErrors<T> = { [K in keyof T]?: string };
type Touched<T> = { [K in keyof T]: boolean };
type Validators<T> = { [K in keyof T]?: (value: T[K]) => string | undefined };
const validators: Validators<CheckoutForm> = {
fullName: (v) => (v.trim().length < 3 ? "Enter your full name" : undefined),
phone: (v) => (/^[6-9]\d{9}$/.test(v) ? undefined : "Enter a valid 10-digit mobile number"),
pincode: (v) => (/^\d{6}$/.test(v) ? undefined : "PIN code must be 6 digits"),
};
function validate<T extends object>(values: T, rules: Validators<T>): FormErrors<T> {
const errors: FormErrors<T> = {};
for (const key of Object.keys(values) as (keyof T)[]) {
const message = rules[key]?.(values[key]);
if (message) errors[key] = message;
}
return errors;
}
const values: CheckoutForm = { fullName: "Ravi Teja", phone: "12345", pincode: "50008", saveAddress: true };
const touched: Touched<CheckoutForm> = { fullName: true, phone: true, pincode: false, saveAddress: false };
const errors = validate(values, validators);
for (const [field, message] of Object.entries(errors)) {
const shown = touched[field as keyof CheckoutForm] ? "shown " : "hidden";
console.log(shown, field.padEnd(8), message);
}Output
shown phone Enter a valid 10-digit mobile number hidden pincode PIN code must be 6 digits