Vue 3 Typed Form Validation
Build type-safe reactive forms in Vue 3 with TypeScript using composable validators, computed error states, and debounced field validation that prevents.
Code
import { ref, computed, type Ref } from 'vue';
interface Rules<T> {
[K in keyof T]?: (v: T[K]) => string | true;
}
export function useTypedForm<T extends Record<string, string>>(
init: T,
rules: Rules<T>,
) {
const values = ref(init) as Ref<T>;
const errors = computed(() => {
const e: Partial<Record<keyof T, string>> = {};
for (const key in rules) {
const result = rules[key]?.(values.value[key]);
if (result !== true && result !== undefined) e[key] = result;
}
return e;
});
const isValid = computed(() => Object.keys(errors.value).length === 0);
return { values, errors, isValid };
}