diff --git a/docs/framework/react/reference/functions/useform.md b/docs/framework/react/reference/functions/useform.md index f0a52bf6e..7b719ee01 100644 --- a/docs/framework/react/reference/functions/useform.md +++ b/docs/framework/react/reference/functions/useform.md @@ -6,7 +6,7 @@ title: useForm # Function: useForm() ```ts -function useForm(opts?): FormApi & ReactFormApi +function useForm(opts?): ReactFormExtendedApi ``` A custom React Hook that returns an extended instance of the `FormApi` class. @@ -25,8 +25,8 @@ This API encapsulates all the necessary functionalities related to the form. It ## Returns -`FormApi`\<`TFormData`, `TFormValidator`\> & [`ReactFormApi`](../interfaces/reactformapi.md)\<`TFormData`, `TFormValidator`\> +[`ReactFormExtendedApi`](../type-aliases/reactformextendedapi.md)\<`TFormData`, `TFormValidator`\> ## Defined in -[useForm.tsx:57](https://github.com/TanStack/form/blob/main/packages/react-form/src/useForm.tsx#L57) +[useForm.tsx:65](https://github.com/TanStack/form/blob/main/packages/react-form/src/useForm.tsx#L65) diff --git a/docs/framework/react/reference/index.md b/docs/framework/react/reference/index.md index 9476d97f2..d79f85b05 100644 --- a/docs/framework/react/reference/index.md +++ b/docs/framework/react/reference/index.md @@ -12,6 +12,7 @@ title: "@tanstack/react-form" ## Type Aliases - [FieldComponent](type-aliases/fieldcomponent.md) +- [ReactFormExtendedApi](type-aliases/reactformextendedapi.md) - [UseField](type-aliases/usefield.md) ## Functions diff --git a/docs/framework/react/reference/type-aliases/reactformextendedapi.md b/docs/framework/react/reference/type-aliases/reactformextendedapi.md new file mode 100644 index 000000000..c0ba2e16b --- /dev/null +++ b/docs/framework/react/reference/type-aliases/reactformextendedapi.md @@ -0,0 +1,22 @@ +--- +id: ReactFormExtendedApi +title: ReactFormExtendedApi +--- + +# Type Alias: ReactFormExtendedApi\ + +```ts +type ReactFormExtendedApi: FormApi & ReactFormApi; +``` + +An extended version of the `FormApi` class that includes React-specific functionalities from `ReactFormApi` + +## Type Parameters + +• **TFormData** + +• **TFormValidator** *extends* `Validator`\<`TFormData`, `unknown`\> \| `undefined` = `undefined` + +## Defined in + +[useForm.tsx:55](https://github.com/TanStack/form/blob/main/packages/react-form/src/useForm.tsx#L55) diff --git a/packages/react-form/src/index.ts b/packages/react-form/src/index.ts index f9000b7e2..8b06e6751 100644 --- a/packages/react-form/src/index.ts +++ b/packages/react-form/src/index.ts @@ -1,6 +1,6 @@ export * from '@tanstack/form-core' -export type { ReactFormApi } from './useForm' +export type { ReactFormApi, ReactFormExtendedApi } from './useForm' export { useForm } from './useForm' export type { UseField, FieldComponent } from './useField' diff --git a/packages/react-form/src/useForm.tsx b/packages/react-form/src/useForm.tsx index dd1f2cac2..10fd104ab 100644 --- a/packages/react-form/src/useForm.tsx +++ b/packages/react-form/src/useForm.tsx @@ -49,6 +49,14 @@ export interface ReactFormApi< }) => NodeType } +/** + * An extended version of the `FormApi` class that includes React-specific functionalities from `ReactFormApi` + */ +export type ReactFormExtendedApi< + TFormData, + TFormValidator extends Validator | undefined = undefined, +> = FormApi & ReactFormApi + /** * A custom React Hook that returns an extended instance of the `FormApi` class. * @@ -61,23 +69,23 @@ export function useForm< const [formApi] = useState(() => { const api = new FormApi(opts) - const extendedApi: typeof api & ReactFormApi = + const extendedApi: ReactFormExtendedApi = api as never extendedApi.Field = function APIField(props) { - return () as never + return } // eslint-disable-next-line react-hooks/rules-of-hooks extendedApi.useField = (props) => useField({ ...props, form: api }) extendedApi.useStore = (selector) => { // eslint-disable-next-line react-hooks/rules-of-hooks - return useStore(api.store as any, selector as any) as any + return useStore(api.store, selector) } extendedApi.Subscribe = (props) => { return functionalUpdate( props.children, // eslint-disable-next-line react-hooks/rules-of-hooks - useStore(api.store as any, props.selector as any), - ) as any + useStore(api.store, props.selector), + ) } return extendedApi diff --git a/packages/react-form/tests/useForm.test-d.tsx b/packages/react-form/tests/useForm.test-d.tsx index d5c2db3dc..7d37e625b 100644 --- a/packages/react-form/tests/useForm.test-d.tsx +++ b/packages/react-form/tests/useForm.test-d.tsx @@ -1,6 +1,6 @@ -import * as React from 'react' import { assertType, it } from 'vitest' import { useForm } from '../src/index' +import type { ReactFormExtendedApi } from '../src/useForm' it('should type onSubmit properly', () => { function Comp() { @@ -34,3 +34,20 @@ it('should type a validator properly', () => { }) } }) + +it('should not have recursion problems and type register properly', () => { + const register = (f: ReactFormExtendedApi) => f + + function Comp() { + const form = useForm({ + defaultValues: { + name: '', + title: '', + }, + }) + + const x = register(form) + + return null + } +})