Types
Validator
The only exported type.
type Validator<Element> = Falsy | ((el: Element) => ValidatorResponse);The element type is a parameter, so annotate the element you are actually attaching to and get a typed argument:
const minLength: Validator<HTMLInputElement> = el => el.value.length < 5 && 'Use at least 5 characters';
const hasSelection: Validator<HTMLSelectElement> = el => el.selectedIndex === 0 && 'Pick an option';Falsy is part of the union so a conditional entry type-checks without a cast:
<input use:validate={[required, needsMatch() && mustMatch]} />Falsy
type Falsy = false | 0 | '' | null | undefined | void;Everything that counts as passing. void is in the union so a validator that just runs if (bad) return message type-checks without an explicit return undefined.
ValidatorResponse
type ValidatorResponse = MaybePromise<string | Falsy>;A message, nothing, or a promise of either.
JSX.Directives
The package augments Solid’s directive interface:
declare module 'solid-js' { namespace JSX { interface Directives { formSubmit: (callback: HTMLFormElement) => any; validate: boolean | Validator<any>[]; } }}The augmentation is applied by importing anything from the package. Two things follow from these signatures:
validate accepts boolean, which is what makes bare use:validate with no value valid. Passing true explicitly is the same as passing nothing.
validate is typed as Validator<any>[], so the array does not narrow to your element. Annotate each validator with its own Validator<HTMLInputElement> to keep the element typed.
Typing errors
useForm<ErrorFields> sets the shape of the store:
type SignupFields = { email: string; password: string; form: string;};
const { errors } = useForm<SignupFields>();Include your form-level keys in the type. They are not tied to any field, but they are keys in the same store, and leaving them out makes errors.form a type error.
validateField and getFieldValue both take keyof ErrorFields, so a form-level key is accepted there too even though no element is registered under it. Both are defined to handle a missing field: validateField resolves false and getFieldValue returns undefined.