Skip to content

Instantly share code, notes, and snippets.

@panrafal
Last active May 19, 2022 19:56
Show Gist options
  • Save panrafal/92e11be4401aee710d8616cf2b664c0d to your computer and use it in GitHub Desktop.
Save panrafal/92e11be4401aee710d8616cf2b664c0d to your computer and use it in GitHub Desktop.
react-hook-form nested forms
import { get } from "lodash"
import { FieldPath, UseFormReturn } from "react-hook-form"
import { Get } from "type-fest"
export type NestedForm<TValues> = UseFormReturn<{ __nested__: TValues }> & {
path(this: void): `__nested__`
path<TPath extends FieldPath<TValues>>(
this: void,
p?: TPath
): `__nested__.${TPath}`
get<TObj>(this: void, obj: TObj): Get<TObj, `__nested__`>
get<TPath extends FieldPath<TValues>, TObj>(
this: void,
obj: TObj,
p?: TPath
): Get<TObj, `__nested__.${TPath}`>
}
export function nestedForm<TValues>(
form: UseFormReturn<TValues> | NestedForm<TValues>
): NestedForm<TValues>
export function nestedForm<TValues, TPath extends FieldPath<TValues>>(
form: UseFormReturn<TValues> | NestedForm<TValues>,
path: TPath
): NestedForm<Get<TValues, TPath>>
export function nestedForm(
form: UseFormReturn<any> | NestedForm<any>,
path?: string | number
): NestedForm<any> {
return {
...form,
path(field?: string | number) {
const fullPath = path && field ? `${path}.${field}` : path ? path : field
if ("path" in form) return form.path(path as any)
return (fullPath || "") as any
},
get(obj: any, field?: string | number) {
const fullPath = path && field ? `${path}.${field}` : path ? path : field
if ("get" in form) return form.get(path)
return fullPath ? get(obj, fullPath) : obj
},
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment