Skip to content

Commit

Permalink
fix: simplify useForm return type (#1016)
Browse files Browse the repository at this point in the history
* fix: simplify useForm return type

* ci: apply automated fixes and generate docs

* fix: restore validator type

* ci: apply automated fixes and generate docs

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
  • Loading branch information
Balastrong and autofix-ci[bot] authored Nov 23, 2024
1 parent c8e9887 commit a85cab8
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 10 deletions.
6 changes: 3 additions & 3 deletions docs/framework/react/reference/functions/useform.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ title: useForm
# Function: useForm()

```ts
function useForm<TFormData, TFormValidator>(opts?): FormApi<TFormData, TFormValidator> & ReactFormApi<TFormData, TFormValidator>
function useForm<TFormData, TFormValidator>(opts?): ReactFormExtendedApi<TFormData, TFormValidator>
```

A custom React Hook that returns an extended instance of the `FormApi` class.
Expand All @@ -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)
1 change: 1 addition & 0 deletions docs/framework/react/reference/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
id: ReactFormExtendedApi
title: ReactFormExtendedApi
---

# Type Alias: ReactFormExtendedApi\<TFormData, TFormValidator\>

```ts
type ReactFormExtendedApi<TFormData, TFormValidator>: FormApi<TFormData, TFormValidator> & ReactFormApi<TFormData, TFormValidator>;
```

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)
2 changes: 1 addition & 1 deletion packages/react-form/src/index.ts
Original file line number Diff line number Diff line change
@@ -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'
Expand Down
18 changes: 13 additions & 5 deletions packages/react-form/src/useForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<TFormData, unknown> | undefined = undefined,
> = FormApi<TFormData, TFormValidator> & ReactFormApi<TFormData, TFormValidator>

/**
* A custom React Hook that returns an extended instance of the `FormApi` class.
*
Expand All @@ -61,23 +69,23 @@ export function useForm<
const [formApi] = useState(() => {
const api = new FormApi<TFormData, TFormValidator>(opts)

const extendedApi: typeof api & ReactFormApi<TFormData, TFormValidator> =
const extendedApi: ReactFormExtendedApi<TFormData, TFormValidator> =
api as never
extendedApi.Field = function APIField(props) {
return (<Field {...props} form={api} />) as never
return <Field {...props} form={api} />
}
// 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
Expand Down
19 changes: 18 additions & 1 deletion packages/react-form/tests/useForm.test-d.tsx
Original file line number Diff line number Diff line change
@@ -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() {
Expand Down Expand Up @@ -34,3 +34,20 @@ it('should type a validator properly', () => {
})
}
})

it('should not have recursion problems and type register properly', () => {
const register = <Data,>(f: ReactFormExtendedApi<Data>) => f

function Comp() {
const form = useForm({
defaultValues: {
name: '',
title: '',
},
})

const x = register(form)

return null
}
})

0 comments on commit a85cab8

Please sign in to comment.