Open fl0ydj opened 2 months ago
Following
First thing I'd try is to replace the temporary workaround ReturnType<typeof useForm<V>>
with the newly exposed ReactFormApi<V>
, in other similar cases this helped already with the type issue.
If that doesn't work, could you please reproduce the case on a stackblitz? You can fork one from the docs (e.g. https://tanstack.com/form/latest/docs/framework/react/examples/simple)
Speaking of custom components, we've been drafting a possible API and recommended pattern in #825 (component example in https://github.com/TanStack/form/pull/825/files#diff-b2e0803ded7363bf3432f160f7c7f6e9bf4f982ad13b08ecb4789c228774f956). Since you're doing something similar your feedback can help shaping the final version :)
Changed it to ReactFormApi<V> & FormApi<V>
. Didn't fix the issue though.
Have been trying to reproduce some of the issues on stackblitz. Have not been able to do so though as it just starts happening once the types are pretty complex. Found one issue, where I had slightly conflicting generics. i.e.:
enum MyEnum {
a,
b,
c
};
type SubEnumType=MyEnum.a|MyEnum.b;
type FormData=FieldValues1&FieldValues2;
type FieldValues1<N extends SubEnumType=SubEnumType>={
fieldVal1:N
}
type FieldValues2={
fieldVal1:MyEnum, //reusing this value here as my field 2 depends on it and consumes it with useStore
fieldVal2: string
}
Changing fieldVal1:MyEnum,
to fieldVal1:SubEnumType,
solved the error in that situation.
I have tried reproducing this in the stackblitz but even this didn't work as presumably my test types were too simple.
Concluding, generally it seems that if the formdata types get too complex, its hard to avoid these ts issues?
Will also give it a couple more tries in the next couple of days
I'm also facing this issue in the project where I'm transitioning from Formik to Tanstack Form so I will likewise try to create a reproducible Stackblitz. So far what I can say is that the error occurs on a function I wrote setFormFieldValue
:
import type { ReactFormApi, DeepKeys, DeepValue, Updater, Validator, FormApi } from '@tanstack/react-form';
export function setFormFieldValue<TFormData, TField extends DeepKeys<TFormData>>(
form: FormApi<TFormData, Validator<TFormData, unknown>> & ReactFormApi<TFormData, Validator<TFormData, unknown>>,
field: TField,
updater: Updater<DeepValue<TFormData, TField>>
) {
form.setFieldValue(field, updater);
form.setFieldMeta(field, {
errors: [],
errorMap: { onChange: false },
isDirty: true,
isTouched: true,
isValidating: false,
isPristine: false
});
}
Which I call from an onChange
to set the value of another field. I noticed that if I only use setFieldValue
(without the additional meta) that our Testing Library tests fail because the proper errors aren't shown, coming from this component:
import type { DeepKeys, DeepValue, FieldApi, Validator } from '@tanstack/react-form';
interface FormErrorProps<
TParentData,
TName extends DeepKeys<TParentData>,
TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined,
TFormValidator extends Validator<TParentData, unknown> | undefined = undefined,
TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>
> {
readonly field: FieldApi<TParentData, TName, TFieldValidator, TFormValidator, TData>;
readonly 'data-qa'?: string;
}
export function FormError<
TParentData,
TName extends DeepKeys<TParentData>,
TFieldValidator extends Validator<DeepValue<TParentData, TName>, unknown> | undefined = undefined,
TFormValidator extends Validator<TParentData, unknown> | undefined = undefined,
TData extends DeepValue<TParentData, TName> = DeepValue<TParentData, TName>
>({ field, 'data-qa': dataQa }: FormErrorProps<TParentData, TName, TFieldValidator, TFormValidator, TData>) {
if (field.state.meta.isTouched && field.state.meta.errors.length) {
const message = field.state.meta.errors.at(0);
const stringMessage = typeof message === 'string' ? message : '';
if (!stringMessage) return null;
return <CustomFormNotification message={stringMessage} severity='error' data-qa={dataQa ?? 'form-error'} />;
}
return null;
}
The type of the form structure where I call this function is:
enum MyEnum {
ONE = 'one',
TWO = 'two'
}
interface MyFormType {
type: MyEnum;
amount: number;
sheetNumber: string | null;
id: string | null;
}
And it's called like so:
setFormFieldValue(form, 'amount', event.target.value === MyEnum.TWO ? 100 : 20);
With the form being:
const form = useForm<MyFormType, Validator<MyFormType, unknown>>({
defaultValues: {
type: MyEnum.ONE,
amount: 20,
sheetNumber: null,
id: props.id
},
onSubmit: ({ value, formApi }) => {
if (value.type === MyEnum.TWO) {
value.sheetNumber = null;
}
reactQueryHook.mutate(value);
formApi.reset();
},
validatorAdapter: yupValidator()
});
For the time being I added an @ts-ignore
on the line that's giving a problem but I do hope this can get fixed some way.
If it matters, this is my system info:
System:
OS: macOS 14.6.1
CPU: (16) x64 Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
Memory: 15.67 MB / 32.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 20.16.0 - /private/var/folders/nk/rds5rlv12dn8yxm9qx6mgv0h0000gn/T/xfs-ad6c1b10/node
Yarn: 4.3.1 - /private/var/folders/nk/rds5rlv12dn8yxm9qx6mgv0h0000gn/T/xfs-ad6c1b10/yarn
npm: 10.8.1 - ~/.volta/tools/image/node/20.16.0/bin/npm
pnpm: 9.7.0 - ~/.volta/bin/pnpm
I recreated the most minimal reproduction possible:
import { FormApi, useForm } from "@tanstack/react-form";
const register = <Data,>(form: FormApi<Data>) => {};
const App = () => {
const form = useForm({
defaultValues: {
name: "",
title: "",
},
});
const x = register(form);
return null;
};
export default App;
It happens in forms with 2 or more fields.
In my case, this problem was caused by having an interface with a property type Moment. This problem still occurs in the latest version 0.32.0
Describe the bug
First off, thanks for the awesome library!
We have been observing some weird instances of "Type instantiation is excessively deep and possibly infinite". For some files, tsc is even crashing.
Our repo is private so can't share it but we created a couple of custom Fields/components, so maybe you can spot where this is coming from:
Code
Code
```javascript type IsDeepValueStringCode
```javascript export const GasEstimateSimulation = ({ gasField, metaData, userCoin, approval, }: { gasField: FieldApiYour minimal, reproducible example
-
Steps to reproduce
See examples above
Expected behavior
Less performance issues with type checking
How often does this bug happen?
None
Screenshots or Videos
No response
Platform
macOs
TanStack Form adapter
None
TanStack Form version
0.26.4
TypeScript version
5.5.4
Additional context
We are using the zod form adaptor at the same version (0.26.4)