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.

Typescript Vue Form Validation

Code

snippet
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 };
}