jaredpalmer / formik

Build forms in React, without the tears 😭
https://formik.org
Apache License 2.0
33.87k stars 2.78k forks source link

Nested types in Formik errors converts Object to string type #3355

Open FBurner opened 2 years ago

FBurner commented 2 years ago

Bug report

Current Behavior

Nested object when accessed via the dot operator gets following error:

TS2339: Property 'budget' does not exist on type 'string'.

Expected behavior

Not to throw this error

Reproducible example

interface CampaignFormValues {
  campaignName?: string;
  **campaignMetrics?: CampaignMetrics;**
  mainPeriod?: Period;
  publishing?: Array<Publishing>;
  jobList?: JobList;
  applicationMethod: ApplicationMethod;
  submit?: any;
}

(
          {
            errors
            handleBlur,
            handleChange,
            handleSubmit,
            isSubmitting,
            touched,
            values,
            status,
          }: FormikProps<CampaignFormValues>
        ) => { errors.campaignMetrics?.budget }

Suggested solution(s)

Make it properly work with injected type.

Its the FormikErrors Type in formik/dist/types.d.ts:13

export declare type FormikErrors<Values> = {
    [K in keyof Values]?: Values[K] extends any[] ? Values[K][number] extends object ? FormikErrors<Values[K][number]>[] | string | string[] : string | string[] : Values[K] extends object ? FormikErrors<Values[K]> : string; 
};

The last FormikErrors<Values[K]> : string; is causing the problem

Your environment

Software Version(s)
Formik ^2.2.9
React 17.0.2
TypeScript 4.1.3
Browser -
npm/Yarn -
Operating System ubuntu
mi-mazouz commented 2 years ago

Any news on this issue?

IgorKushnir commented 1 year ago

Same, looking for some solution

dvalsagna89 commented 1 year ago

https://medium.com/@arfizrahman0/react-form-validation-having-nested-schema-with-formik-yup-and-material-ui-e2a2bb4e0356

@IgorKushnir @mi-mazouz @FBurner you can use getIn function

adi518 commented 1 month ago

If you have a wrapper around Fomik, you can mitigate this issue rather easily, by copy-pasting the type above from the source (for the latest version) and fixing it by removing the last bit as OP indicated. It now works correctly with nested fields. I'm not even sure why the string type is even relevant. Would be great If someone can elaborate on a Formik usage that applies to it.

// https://github.com/jaredpalmer/formik/blob/c798145e2307b0273ea4d9c6bfd8250f28d95be9/packages/formik/src/types.tsx#L14
export type FormikErrors<Values> = {
  [K in keyof Values]?: Values[K] extends any[]
    ? Values[K][number] extends object
      ? FormikErrors<Values[K][number]>[] | string | string[]
      : string | string[]
    : FormikErrors<Values[K]>;
};

Alternatively, you can use patch-package (some package managers have this feature built-in) to fix it at the import level, which should be pretty easy.