After upgrading from Formik 1 -> Formik 2, FormikProps has become too strict and can no longer be used in generic components. For example:
const formik = useFormik({
initialValues: {
foo: "",
bar: ""
},
...
});
const genericFormikProps: FormikProps<FormikValues> = formik;
results in:
Type '{ initialValues: { foo: string; bar: string; }; initialErrors: FormikErrors<unknown>; initialTouched: FormikTouched<unknown>; initialStatus: any; handleBlur: (eventOrString: any) => void | ((e: any) => void); ... 32 more ...; submitCount: number; }' is not assignable to type 'FormikProps<FormikValues>'.
Type '{ initialValues: { foo: string; bar: string; }; initialErrors: FormikErrors<unknown>; initialTouched: FormikTouched<unknown>; initialStatus: any; handleBlur: (eventOrString: any) => void | ((e: any) => void); ... 32 more ...; submitCount: number; }' is not assignable to type 'FormikHelpers<FormikValues>'.
Types of property 'setFormikState' are incompatible.
Type '(stateOrCb: FormikState<{ foo: string; bar: string; }> | ((state: FormikState<{ foo: string; bar: string; }>) => FormikState<{ foo: string; bar: string; }>)) => void' is not assignable to type '(f: FormikState<FormikValues> | ((prevState: FormikState<FormikValues>) => FormikState<FormikValues>), cb?: (() => void) | undefined) => void'.
Types of parameters 'stateOrCb' and 'f' are incompatible.
Type 'FormikState<FormikValues> | ((prevState: FormikState<FormikValues>) => FormikState<FormikValues>)' is not assignable to type 'FormikState<{ foo: string; bar: string; }> | ((state: FormikState<{ foo: string; bar: string; }>) => FormikState<{ foo: string; bar: string; }>)'.
Type 'FormikState<FormikValues>' is not assignable to type 'FormikState<{ foo: string; bar: string; }> | ((state: FormikState<{ foo: string; bar: string; }>) => FormikState<{ foo: string; bar: string; }>)'.
Type 'FormikState<FormikValues>' is not assignable to type 'FormikState<{ foo: string; bar: string; }>'.
Types of property 'values' are incompatible.
Type 'FormikValues' is not assignable to type '{ foo: string; bar: string; }'
I expected the type definition to allow the same assignments it did before Formik 2.
Here's a somewhat realistic example of the kind of component that this change has broken:
https://codesandbox.io/s/react-typescript-4sc41
Is this intentional or is it a bug? If it's not a bug, please document the intended migration path for components that use generic FormikProps.
| Software | Version(s) |
| ---------------- | ---------- |
| Formik | 2.1.0
| React | 16.12.0
| TypeScript | 3.7.4
| Browser | N/A
| npm/Yarn | N/A
| Operating System | N/A
You can remove the property from props and omit it from the interface as a workaround.
Destructure props:
const { setFormikState, ...rest } = formik;
const { errors, touched, values } = rest;
Interface:
export interface ICustomFormikProps extends Omit<FormikProps<FormikValues>,"setFormikState"> {}
Not exactly ideal, but...
@mhaagens solution worked so far, but Formik v2.1.5 added some extra type definitions.
The new solution is to also Omit setValues and resetForm
Omit<FormikProps<FormikValues>, 'setFormikState' | 'setValues' | 'resetForm'>
Or use generics where <T extends FormikValues>
Oof we should fix this. Can someone make a PR?
Most helpful comment
@mhaagens solution worked so far, but Formik v2.1.5 added some extra type definitions.
The new solution is to also Omit
setValuesandresetFormOmit<FormikProps<FormikValues>, 'setFormikState' | 'setValues' | 'resetForm'>Or use generics where
<T extends FormikValues>