Performant, flexible and extensible forms with easy to use validation.
React Hook Form strictly typed custom hooks.
$ npm install @hookform/strictly-typed
import { useTypedController } from '@hookform/strictly-typed';
import { useForm } from 'react-hook-form';
import { TextField, Checkbox } from '@material-ui/core';
type FormValues = {
  flat: string;
  nested: {
    object: { test: string };
    array: { test: boolean }[];
  };
};
export default function App() {
  const { control, handleSubmit } = useForm<FormValues>();
  const TypedController = useTypedController<FormValues>({ control });
  const onSubmit = handleSubmit((data) => console.log(data));
  return (
    <form onSubmit={onSubmit}>
      <TypedController
        name="flat"
        defaultValue=""
        render={(props) => <TextField {...props} />}
      />
      <TypedController
        as="textarea"
        name={['nested', 'object', 'test']}
        defaultValue=""
        rules={{ required: true }}
      />
      <TypedController
        name={['nested', 'array', 0, 'test']}
        defaultValue={false}
        render={(props) => <Checkbox {...props} />}
      />
      {/* β: Type '"notExists"' is not assignable to type 'DeepPath<FormValues, "notExists">'. */}
      <TypedController as="input" name="notExists" defaultValue="" />
      {/* β: Type 'number' is not assignable to type 'string | undefined'. */}
      <TypedController
        as="input"
        name={['nested', 'object', 0, 'notExists']}
        defaultValue=""
      />
      {/* β: Type 'true' is not assignable to type 'string | undefined'. */}
      <TypedController as="input" name="flat" defaultValue={true} />
      <input type="submit" />
    </form>
  );
}| Field Path | Field Name | 
|---|---|
| foo | foo | 
| ['foo', 'bar'] | foo.bar | 
| ['foo', 0] | foo[0] | 
| ['foo', '0'] | foo.0 | 
| ['foo', 1] | foo[1] | 
| ['foo', 0, 'bar'] | foo[0].bar | 
| ['foo'] | foo | 
| ['foo', 'bar'] | foo.bar | 
| ['foo', 'bar', 0] | foo.bar[0] | 
- useTypedController
| Name | Type | Required | 
|---|---|---|
| control | Object | 
- TypedController
| Name | Type | Required | 
|---|---|---|
| name | string | [string, ...(string | number)[]] | β | 
| as | 'input' | 'select' | 'textarea' | |
| render | Function | |
| defaultValue | DeepPathValue | |
| rules | Object | |
| onFocus | () => void | 
Thanks goes to all our backers! [Become a backer].
Thanks goes to these wonderful organizations! [Contribute].
Thanks goes to these wonderful people! [Become a contributor].
