Skip to content

Commit 062f55e

Browse files
fix(form-core): fix typing for formOptions so they don't override additional args passed to form (#1239)
* fix(form-core): fix typing for formOptions so they don't override additional args passed to form * ci: apply automated fixes and generate docs --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
1 parent dfd6a68 commit 062f55e

File tree

13 files changed

+343
-206
lines changed

13 files changed

+343
-206
lines changed

docs/framework/react/reference/functions/createformhook.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ title: createFormHook
1111
function createFormHook<TComponents, TFormComponents>(__namedParameters): object
1212
```
1313

14-
Defined in: [packages/react-form/src/createFormHook.tsx:186](https://github.com/TanStack/form/blob/main/packages/react-form/src/createFormHook.tsx#L186)
14+
Defined in: [packages/react-form/src/createFormHook.tsx:188](https://github.com/TanStack/form/blob/main/packages/react-form/src/createFormHook.tsx#L188)
1515

1616
## Type Parameters
1717

@@ -111,7 +111,7 @@ withForm: <TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync
111111

112112
###### props
113113

114-
`PropsWithChildren`\<`NoInfer`\<`TRenderProps`\> & `object`\>
114+
`PropsWithChildren`\<`NoInfer`\<`UnwrapOrAny`\<`TRenderProps`\>\> & `object`\>
115115

116116
##### Returns
117117

docs/framework/react/reference/functions/createformhookcontexts.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ title: createFormHookContexts
1111
function createFormHookContexts(): object
1212
```
1313

14-
Defined in: [packages/react-form/src/createFormHook.tsx:16](https://github.com/TanStack/form/blob/main/packages/react-form/src/createFormHook.tsx#L16)
14+
Defined in: [packages/react-form/src/createFormHook.tsx:18](https://github.com/TanStack/form/blob/main/packages/react-form/src/createFormHook.tsx#L18)
1515

1616
## Returns
1717

docs/framework/react/reference/functions/usetransform.md

+4-26
Original file line numberDiff line numberDiff line change
@@ -8,43 +8,21 @@ title: useTransform
88
# Function: useTransform()
99

1010
```ts
11-
function useTransform<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer, TSubmitMeta>(fn, deps): FormTransform<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer, TSubmitMeta>
11+
function useTransform(fn, deps): FormTransform<any, any, any, any, any, any, any, any, any, any>
1212
```
1313

14-
Defined in: [packages/react-form/src/useTransform.ts:8](https://github.com/TanStack/form/blob/main/packages/react-form/src/useTransform.ts#L8)
15-
16-
## Type Parameters
17-
18-
**TFormData**
19-
20-
**TOnMount** *extends* `undefined` \| `FormValidateOrFn`\<`TFormData`\>
21-
22-
**TOnChange** *extends* `undefined` \| `FormValidateOrFn`\<`TFormData`\>
23-
24-
**TOnChangeAsync** *extends* `undefined` \| `FormAsyncValidateOrFn`\<`TFormData`\>
25-
26-
**TOnBlur** *extends* `undefined` \| `FormValidateOrFn`\<`TFormData`\>
27-
28-
**TOnBlurAsync** *extends* `undefined` \| `FormAsyncValidateOrFn`\<`TFormData`\>
29-
30-
**TOnSubmit** *extends* `undefined` \| `FormValidateOrFn`\<`TFormData`\>
31-
32-
**TOnSubmitAsync** *extends* `undefined` \| `FormAsyncValidateOrFn`\<`TFormData`\>
33-
34-
**TOnServer** *extends* `undefined` \| `FormAsyncValidateOrFn`\<`TFormData`\>
35-
36-
**TSubmitMeta**
14+
Defined in: [packages/react-form/src/useTransform.ts:9](https://github.com/TanStack/form/blob/main/packages/react-form/src/useTransform.ts#L9)
3715

3816
## Parameters
3917

4018
### fn
4119

42-
(`formBase`) => `FormApi`\<`TFormData`, `TOnMount`, `TOnChange`, `TOnChangeAsync`, `TOnBlur`, `TOnBlurAsync`, `TOnSubmit`, `TOnSubmitAsync`, `TOnServer`, `TSubmitMeta`\>
20+
(`formBase`) => `AnyFormApi`
4321

4422
### deps
4523

4624
`unknown`[]
4725

4826
## Returns
4927

50-
`FormTransform`\<`TFormData`, `TOnMount`, `TOnChange`, `TOnChangeAsync`, `TOnBlur`, `TOnBlurAsync`, `TOnSubmit`, `TOnSubmitAsync`, `TOnServer`, `TSubmitMeta`\>
28+
`FormTransform`\<`any`, `any`, `any`, `any`, `any`, `any`, `any`, `any`, `any`, `any`\>

docs/framework/react/reference/interfaces/withformprops.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ title: WithFormProps
77

88
# Interface: WithFormProps\<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer, TSubmitMeta, TFieldComponents, TFormComponents, TRenderProps\>
99

10-
Defined in: [packages/react-form/src/createFormHook.tsx:136](https://github.com/TanStack/form/blob/main/packages/react-form/src/createFormHook.tsx#L136)
10+
Defined in: [packages/react-form/src/createFormHook.tsx:138](https://github.com/TanStack/form/blob/main/packages/react-form/src/createFormHook.tsx#L138)
1111

1212
## Extends
1313

@@ -49,7 +49,7 @@ Defined in: [packages/react-form/src/createFormHook.tsx:136](https://github.com/
4949
optional props: TRenderProps;
5050
```
5151

52-
Defined in: [packages/react-form/src/createFormHook.tsx:163](https://github.com/TanStack/form/blob/main/packages/react-form/src/createFormHook.tsx#L163)
52+
Defined in: [packages/react-form/src/createFormHook.tsx:165](https://github.com/TanStack/form/blob/main/packages/react-form/src/createFormHook.tsx#L165)
5353

5454
***
5555

@@ -59,7 +59,7 @@ Defined in: [packages/react-form/src/createFormHook.tsx:163](https://github.com/
5959
render: (props) => Element;
6060
```
6161

62-
Defined in: [packages/react-form/src/createFormHook.tsx:164](https://github.com/TanStack/form/blob/main/packages/react-form/src/createFormHook.tsx#L164)
62+
Defined in: [packages/react-form/src/createFormHook.tsx:166](https://github.com/TanStack/form/blob/main/packages/react-form/src/createFormHook.tsx#L166)
6363

6464
#### Parameters
6565

docs/reference/functions/formoptions.md

+5-26
Original file line numberDiff line numberDiff line change
@@ -8,42 +8,21 @@ title: formOptions
88
# Function: formOptions()
99

1010
```ts
11-
function formOptions<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer, TSubmitMeta>(defaultOpts?):
12-
| undefined
13-
| FormOptions<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer, TSubmitMeta>
11+
function formOptions<T>(defaultOpts): T
1412
```
1513

1614
Defined in: [packages/form-core/src/formOptions.ts:7](https://github.com/TanStack/form/blob/main/packages/form-core/src/formOptions.ts#L7)
1715

1816
## Type Parameters
1917

20-
**TFormData**
21-
22-
**TOnMount** *extends* `undefined` \| `FormValidateOrFn`\<`TFormData`\>
23-
24-
**TOnChange** *extends* `undefined` \| `FormValidateOrFn`\<`TFormData`\>
25-
26-
**TOnChangeAsync** *extends* `undefined` \| `FormAsyncValidateOrFn`\<`TFormData`\>
27-
28-
**TOnBlur** *extends* `undefined` \| `FormValidateOrFn`\<`TFormData`\>
29-
30-
**TOnBlurAsync** *extends* `undefined` \| `FormAsyncValidateOrFn`\<`TFormData`\>
31-
32-
**TOnSubmit** *extends* `undefined` \| `FormValidateOrFn`\<`TFormData`\>
33-
34-
**TOnSubmitAsync** *extends* `undefined` \| `FormAsyncValidateOrFn`\<`TFormData`\>
35-
36-
**TOnServer** *extends* `undefined` \| `FormAsyncValidateOrFn`\<`TFormData`\>
37-
38-
**TSubmitMeta**
18+
**T** *extends* `Partial`\<[`FormOptions`](../interfaces/formoptions.md)\<`any`, `any`, `any`, `any`, `any`, `any`, `any`, `any`, `any`, `any`\>\>
3919

4020
## Parameters
4121

42-
### defaultOpts?
22+
### defaultOpts
4323

44-
[`FormOptions`](../interfaces/formoptions.md)\<`TFormData`, `TOnMount`, `TOnChange`, `TOnChangeAsync`, `TOnBlur`, `TOnBlurAsync`, `TOnSubmit`, `TOnSubmitAsync`, `TOnServer`, `TSubmitMeta`\>
24+
`T`
4525

4626
## Returns
4727

48-
\| `undefined`
49-
\| [`FormOptions`](../interfaces/formoptions.md)\<`TFormData`, `TOnMount`, `TOnChange`, `TOnChangeAsync`, `TOnBlur`, `TOnBlurAsync`, `TOnSubmit`, `TOnSubmitAsync`, `TOnServer`, `TSubmitMeta`\>
28+
`T`

docs/reference/interfaces/formoptions.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ onSubmitMeta, the data passed from the handleSubmit handler, to the onSubmit fun
158158
### transform?
159159

160160
```ts
161-
optional transform: FormTransform<TFormData, TOnMount, TOnChange, TOnChangeAsync, TOnBlur, TOnBlurAsync, TOnSubmit, TOnSubmitAsync, TOnServer, TSubmitMeta>;
161+
optional transform: FormTransform<NoInfer<TFormData>, NoInfer<TOnMount>, NoInfer<TOnChange>, NoInfer<TOnChangeAsync>, NoInfer<TOnBlur>, NoInfer<TOnBlurAsync>, NoInfer<TOnSubmit>, NoInfer<TOnSubmitAsync>, NoInfer<TOnServer>, NoInfer<TSubmitMeta>>;
162162
```
163163

164164
Defined in: [packages/form-core/src/FormApi.ts:333](https://github.com/TanStack/form/blob/main/packages/form-core/src/FormApi.ts#L333)

packages/form-core/src/FormApi.ts

+10-10
Original file line numberDiff line numberDiff line change
@@ -331,16 +331,16 @@ export interface FormOptions<
331331
>
332332
}) => void
333333
transform?: FormTransform<
334-
TFormData,
335-
TOnMount,
336-
TOnChange,
337-
TOnChangeAsync,
338-
TOnBlur,
339-
TOnBlurAsync,
340-
TOnSubmit,
341-
TOnSubmitAsync,
342-
TOnServer,
343-
TSubmitMeta
334+
NoInfer<TFormData>,
335+
NoInfer<TOnMount>,
336+
NoInfer<TOnChange>,
337+
NoInfer<TOnChangeAsync>,
338+
NoInfer<TOnBlur>,
339+
NoInfer<TOnBlurAsync>,
340+
NoInfer<TOnSubmit>,
341+
NoInfer<TOnSubmitAsync>,
342+
NoInfer<TOnServer>,
343+
NoInfer<TSubmitMeta>
344344
>
345345
}
346346

packages/form-core/src/formOptions.ts

+3-23
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,9 @@ import type {
55
} from './FormApi'
66

77
export function formOptions<
8-
TFormData,
9-
TOnMount extends undefined | FormValidateOrFn<TFormData>,
10-
TOnChange extends undefined | FormValidateOrFn<TFormData>,
11-
TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,
12-
TOnBlur extends undefined | FormValidateOrFn<TFormData>,
13-
TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,
14-
TOnSubmit extends undefined | FormValidateOrFn<TFormData>,
15-
TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,
16-
TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,
17-
TSubmitMeta,
18-
>(
19-
defaultOpts?: FormOptions<
20-
TFormData,
21-
TOnMount,
22-
TOnChange,
23-
TOnChangeAsync,
24-
TOnBlur,
25-
TOnBlurAsync,
26-
TOnSubmit,
27-
TOnSubmitAsync,
28-
TOnServer,
29-
TSubmitMeta
8+
T extends Partial<
9+
FormOptions<any, any, any, any, any, any, any, any, any, any>
3010
>,
31-
) {
11+
>(defaultOpts: T) {
3212
return defaultOpts
3313
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { assertType, describe, expect, it } from 'vitest'
2+
import { FormApi, formOptions } from '../src/index'
3+
4+
describe('formOptions', () => {
5+
it('types should be properly inferred', () => {
6+
type Person = {
7+
firstName: string
8+
lastName: string
9+
}
10+
11+
const formOpts = formOptions({
12+
defaultValues: {
13+
firstName: 'FirstName',
14+
lastName: 'LastName',
15+
} as Person,
16+
})
17+
18+
const form = new FormApi({
19+
...formOpts,
20+
})
21+
22+
assertType<Person>(form.state.values)
23+
})
24+
25+
it('types should be properly inferred when passing args alongside formOptions', () => {
26+
type Person = {
27+
firstName: string
28+
lastName: string
29+
}
30+
31+
const formOpts = formOptions({
32+
defaultValues: {
33+
firstName: 'FirstName',
34+
lastName: 'LastName',
35+
} as Person,
36+
})
37+
38+
const form = new FormApi({
39+
...formOpts,
40+
onSubmitMeta: {
41+
test: 'test',
42+
},
43+
})
44+
45+
assertType<(submitMeta: { test: string }) => Promise<void>>(
46+
form.handleSubmit,
47+
)
48+
})
49+
50+
it('types should be properly inferred when formOptions are being overridden', () => {
51+
type Person = {
52+
firstName: string
53+
lastName: string
54+
}
55+
56+
type PersonWithAge = Person & {
57+
age: number
58+
}
59+
60+
const formOpts = formOptions({
61+
defaultValues: {
62+
firstName: 'FirstName',
63+
lastName: 'LastName',
64+
} as Person,
65+
})
66+
67+
const form = new FormApi({
68+
...formOpts,
69+
defaultValues: {
70+
firstName: 'FirstName',
71+
lastName: 'LastName',
72+
age: 10,
73+
},
74+
})
75+
76+
assertType<PersonWithAge>(form.state.values)
77+
})
78+
})

packages/react-form/src/createFormHook.tsx

+15-13
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import type { ComponentType, Context, JSX, PropsWithChildren } from 'react'
1313
import type { FieldComponent } from './useField'
1414
import type { ReactFormExtendedApi } from './useForm'
1515

16+
type UnwrapOrAny<T> = [T] extends [unknown] ? any : T
17+
1618
export function createFormHookContexts() {
1719
// We should never hit the `null` case here
1820
const fieldContext = createContext<AnyFieldApi>(null as never)
@@ -308,19 +310,19 @@ export function createFormHook<
308310
TFormComponents,
309311
TRenderProps
310312
>): WithFormProps<
311-
TFormData,
312-
TOnMount,
313-
TOnChange,
314-
TOnChangeAsync,
315-
TOnBlur,
316-
TOnBlurAsync,
317-
TOnSubmit,
318-
TOnSubmitAsync,
319-
TOnServer,
320-
TSubmitMeta,
321-
TComponents,
322-
TFormComponents,
323-
TRenderProps
313+
UnwrapOrAny<TFormData>,
314+
UnwrapOrAny<TOnMount>,
315+
UnwrapOrAny<TOnChange>,
316+
UnwrapOrAny<TOnChangeAsync>,
317+
UnwrapOrAny<TOnBlur>,
318+
UnwrapOrAny<TOnBlurAsync>,
319+
UnwrapOrAny<TOnSubmit>,
320+
UnwrapOrAny<TOnSubmitAsync>,
321+
UnwrapOrAny<TOnServer>,
322+
UnwrapOrAny<TSubmitMeta>,
323+
UnwrapOrAny<TComponents>,
324+
UnwrapOrAny<TFormComponents>,
325+
UnwrapOrAny<TRenderProps>
324326
>['render'] {
325327
return (innerProps) => render({ ...props, ...innerProps })
326328
}

packages/react-form/src/useTransform.ts

+4-38
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,15 @@
11
import type {
2+
AnyFormApi,
23
FormApi,
34
FormAsyncValidateOrFn,
45
FormTransform,
56
FormValidateOrFn,
67
} from '@tanstack/form-core'
78

8-
export function useTransform<
9-
TFormData,
10-
TOnMount extends undefined | FormValidateOrFn<TFormData>,
11-
TOnChange extends undefined | FormValidateOrFn<TFormData>,
12-
TOnChangeAsync extends undefined | FormAsyncValidateOrFn<TFormData>,
13-
TOnBlur extends undefined | FormValidateOrFn<TFormData>,
14-
TOnBlurAsync extends undefined | FormAsyncValidateOrFn<TFormData>,
15-
TOnSubmit extends undefined | FormValidateOrFn<TFormData>,
16-
TOnSubmitAsync extends undefined | FormAsyncValidateOrFn<TFormData>,
17-
TOnServer extends undefined | FormAsyncValidateOrFn<TFormData>,
18-
TSubmitMeta,
19-
>(
20-
fn: (
21-
formBase: FormApi<any, any, any, any, any, any, any, any, any, any>,
22-
) => FormApi<
23-
TFormData,
24-
TOnMount,
25-
TOnChange,
26-
TOnChangeAsync,
27-
TOnBlur,
28-
TOnBlurAsync,
29-
TOnSubmit,
30-
TOnSubmitAsync,
31-
TOnServer,
32-
TSubmitMeta
33-
>,
9+
export function useTransform(
10+
fn: (formBase: AnyFormApi) => AnyFormApi,
3411
deps: unknown[],
35-
): FormTransform<
36-
TFormData,
37-
TOnMount,
38-
TOnChange,
39-
TOnChangeAsync,
40-
TOnBlur,
41-
TOnBlurAsync,
42-
TOnSubmit,
43-
TOnSubmitAsync,
44-
TOnServer,
45-
TSubmitMeta
46-
> {
12+
): FormTransform<any, any, any, any, any, any, any, any, any, any> {
4713
return {
4814
fn,
4915
deps,

0 commit comments

Comments
 (0)