How to add strongly typed field in Formik by typescript?

I tried to add strongly typed in Formik react library by typescript, but I didn’t do that. Of course, I have used this link, but I couldn’t solve my issue.
https://jaredpalmer.com/formik/docs/guides/typescript

I have got this error from this part of code(})(ActivityForm);):

Argument of type ‘(props: IProps) => Element’ is not assignable to
parameter of type ‘CompositeComponent
& FormikState & FormikHelpers & FormikHandlers & FormikComputedProps &
FormikRegistration & { …; }>’. Type ‘(props: IProps) => Element’ is
not assignable to type ‘FunctionComponent & FormikState & FormikHelpers & FormikHandlers
& FormikComputedProps & FormikRegistration & { …; }>’. Types of
parameters ‘props’ and ‘props’ are incompatible. Property
‘setEditMode’ is missing in type ‘FormikSharedConfig<{}> & FormikState
& FormikHelpers & FormikHandlers & FormikComputedProps &
FormikRegistration & { …; } & { …; }’ but required in type
‘IProps’.ts(2345) ActivityForm.tsx(7, 3): ‘setEditMode’ is declared
here.


const ActivityForm: React.FunctionComponent Argument of type
‘FunctionComponent’ is not assignable to parameter of type
‘CompositeComponent &
FormikState & FormikHelpers &
FormikHandlers & FormikComputedProps &
FormikRegistration & { …; }>’. Type ‘FunctionComponent’ is
not assignable to type ‘FunctionComponent & FormikState &
FormikHelpers & FormikHandlers &
FormikComputedProps & FormikRegistration & { …; }>’.
Types of property ‘propTypes’ are incompatible.
Type ‘WeakValidationMap | undefined’ is not assignable to type ‘WeakValidationMap &
FormikState & FormikHelpers &
FormikHandlers & FormikComputedProps &
FormikRegistration & { …; }> | undefined’.
Type ‘WeakValidationMap’ is not assignable to type ‘WeakValidationMap &
FormikState & FormikHelpers &
FormikHandlers & FormikComputedProps &
FormikRegistration & { …; }>’.
Types of property ‘setFormikState’ are incompatible.
Type ‘Validator<(f: FormikState | ((prevState: FormikState) => FormikState),
cb?: (() => void) | undefined) => void> | undefined’ is not assignable
to type ‘Validator<(f: FormikState | ((prevState:
FormikState) => FormikState), cb?: (() =>
void) | undefined) => void> | undefined’.
Type ‘Validator<(f: FormikState | ((prevState: FormikState) => FormikState),
cb?: (() => void) | undefined) => void>’ is not assignable to type
‘Validator<(f: FormikState | ((prevState:
FormikState) => FormikState), cb?: (() =>
void) | undefined) => void>’.
Type ‘(f: FormikState | ((prevState: FormikState) => FormikState), cb?: (() =>
void) | undefined) => void’ is not assignable to type ‘(f:
FormikState | ((prevState: FormikState) =>
FormikState), cb?: (() => void) | undefined) => void’.
Types of parameters ‘f’ and ‘f’ are incompatible.
Type ‘FormikState | ((prevState: FormikState) => FormikState)’ is not
assignable to type ‘FormikState | ((prevState:
FormikState) => FormikState)’.
Type ‘FormikState’ is not assignable to type ‘FormikState | ((prevState:
FormikState) => FormikState)’.
Type ‘FormikState’ is not assignable to type ‘FormikState’.ts(2345) Peek Problem
No quick fixes available


this error comes from ActivityDashboard.tsx

Type ‘{ setEditMode: (editMode: boolean) => void; title: string;
description: string; category: string; city: string; venue: string;
date: string; }’ is missing the following properties from type
‘IProps’: values, errors, touched, isSubmitting, and 28 more.ts(2740)


import React from "react";
import * as yup from "yup";
import { withFormik, Form, Field, FormikProps } from "formik";


interface IProps {
  setEditMode: (editMode: boolean) => void;
}

export const ActivityForm = (props: IProps) => {
  const { setEditMode } = props;
  return (
    <Form>
      <Field type="text" name="title" placeholder="Title" />
      <Field
        type="text"
        rows={2}
        name="description"
        placeholder="Description"
      />
      <Field type="text" name="category" placeholder="Category" />
      <Field type="date" name="date" placeholder="Date" />
      <Field type="text" name="city" placeholder="City" />
      <Field type="text" name="venue" placeholder="Venue" />
      <button type="submit">Edit</button>
      <button type="button" onClick={() => setEditMode(false)}>
        Cancel
      </button>
    </Form>
  );
};

const myForm = withFormik({
  mapPropsToValues: props => {
    return {};
  },
  validationSchema: yup.object().shape({
    title: yup.string().required()
  }),
  handleSubmit(values) {
    console.log(values);
  }
})(ActivityForm);

export default myForm;

import React from "react";
import { IActivity } from "../../../app/models/activity";
import { ActivityList } from "./ActivityList";
import { Col, Row } from "antd";
import { ActivityDetails } from "../details/ActivityDetails";
import { ActivityForm } from "../form/ActivityForm";

interface IProps {
  activities: IActivity[];
  selectActivity: (id: string) => void;
  selectedActivity: IActivity | null;
  editMode: boolean;
  setEditMode: (editMode: boolean) => void;
  setSelectedActivity: (activity: IActivity | null) => void;
}

export const ActivityDashboard: React.FC<IProps> = ({
  activities,
  selectActivity,
  selectedActivity,
  editMode,
  setEditMode,
  setSelectedActivity
}) => {
  return (
    <Row>
      <Col span={3}></Col>
      <Col span={10}>
        <ActivityList activities={activities} selectActivity={selectActivity} />
      </Col>
      <Col span={1}></Col>
      <Col span={6}>
        {selectedActivity && !editMode && (
          <ActivityDetails
            activity={selectedActivity}
            setEditMode={setEditMode}
            setSelectedActivity={setSelectedActivity}
          />
        )}
        {editMode && (
          <ActivityForm
            setEditMode={setEditMode}
            title="alex"
            description="hi"
            category="human"
            city="newyork"
            venue="sd"
            date="2019"
          />
        )}
      </Col>
    </Row>
  );
};

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

I think there are multiple issues here which causes the confusing message from the TypeScript compiler:

  1. First of all, make sure that your functional component extends the React.FC<Props> type so that TypeScript knows that this is a React component:
    import * as React from 'react';
    
    export const ActivityForm : React.FC<IProps> = (props) => {
    ...
  2. Then you have to extend your IProps-type with the FormikProps-type from the formik package, because the withFormik-method only accepts React-components whose props are extend from this type:
    import { FormikProps } from 'formik';
    
    interface MyFormValues {
      title: string;
      category: string;
      description: string;
    }
    
    interface IProps extends FormikProps<MyFormValues> {
      setEditMode(arg: boolean): void;
    }

Your final code should then look like this (Make sure to add the missing properties to the MyFormValues interface):

import * as React from 'react';
import { withFormik, Form, Field, FormikProps } from 'formik';
import * as Yup from 'yup';

interface MyFormValues {
  title: string;
  category: string;
  description: string;
  ...
}

interface IProps extends FormikProps<MyFormValues> {
  setEditMode(arg: boolean): void;
}

export const ActivityForm: React.FC<IProps> = props => {
  const { setEditMode } = props;
  return (
    <Form>
      <Field type="text" name="title" placeholder="Title" />
      <Field
        type="text"
        rows={2}
        name="description"
        placeholder="Description"
      />
      <Field type="text" name="category" placeholder="Category" />
      <Field type="date" name="date" placeholder="Date" />
      <Field type="text" name="city" placeholder="City" />
      <Field type="text" name="venue" placeholder="Venue" />
      <button type="submit">Edit</button>
      <button type="button" onClick={() => setEditMode(false)}>
        Cancel
      </button>
    </Form>
  );
};

const myForm = withFormik({
  mapPropsToValues: props => {
    return {};
  },
  validationSchema: Yup.object().shape({
    title: Yup.string().required()
  }),
  handleSubmit(values) {
    console.log(values);
  }
})(ActivityForm);

export default myForm;

Also here is a CodeSandbox with the final code: https://codesandbox.io/s/stackoverflow59057524-s9ouc?module=%2Fsrc%2FActivityForm.tsx


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x