如何通过typescript在 Formik 中添加强类型字段?

IT技术 reactjs typescript formik
2021-05-08 10:11:14

我试图通过typescript在 Formik react库中添加强类型,但我没有这样做。当然,我已经使用了这个链接,但是我无法解决我的问题。 https://jaredpalmer.com/formik/docs/guides/typescript

我从这部分代码(})(ActivityForm);)中得到了这个错误:

'(props: IProps) => Element' 类型的参数不可分配给'CompositeComponent & FormikState & FormikHelpers & FormikHandlers & FormikComputedProps & FormikRegistration & { ...; }>'。类型 '(props: IProps) => Element' 不可分配给类型 'FunctionComponent & FormikState & FormikHelpers & FormikHandlers & FormikComputedProps & FormikRegistration & { ...; }>'。参数 'props' 和 'props' 的类型不兼容。“FormikSharedConfig<{}> & FormikState & FormikHelpers & FormikHandlers & FormikComputedProps & FormikRegistration & { ...;; } & { ...; }' 但在'IProps'类型中是必需的。


const ActivityForm:'FunctionComponent' 类型的 React.FunctionComponent 参数不可分配给类型'CompositeComponent & FormikState & FormikHelpers & FormikHandlers & FormikComputedProps & FormikRegistration & { ...; }>'。类型“FunctionComponent”不可分配给类型“FunctionComponent & FormikState & FormikHelpers & FormikHandlers & FormikComputedProps & FormikRegistration & { ...; }>'。属性“propTypes”的类型不兼容。输入'WeakValidationMap | undefined' 不可分配给类型 'WeakValidationMap & FormikState & FormikHelpers & FormikHandlers & FormikComputedProps & FormikRegistration & { ...; }> | 不明确的'。类型 ' WeakValidationMap' 不可分配给类型 'WeakValidationMap & FormikState & FormikHelpers & FormikHandlers & FormikComputedProps & FormikRegistration & { ...; }>'。属性“setFormikState”的类型不兼容。输入 'Validator<(f: FormikState | ((prevState: FormikState) => FormikState), cb?: (() => void) | undefined) => void> | undefined' 不可分配给类型 'Validator<(f: FormikState | ((prevState: FormikState) => FormikState), cb?: (() => void) | undefined) => void> | 不明确的'。类型 'Validator<(f: FormikState | ((prevState: FormikState) => FormikState), cb?: (() => void) | undefined) => void>' 不可分配给类型 'Validator<(f: FormikState | ((prevState: FormikState) => FormikState), cb?: (() => void) | 未定义) => void>'。类型 '(f: FormikState | ((prevState: FormikState) => FormikState), cb?: (() => void) | undefined) => void' 不可分配给类型 '(f: FormikState | ((prevState: FormikState) => FormikState), cb?: (() => void) | undefined) => void'。参数“f”和“f”的类型不兼容。输入'FormikState | ((prevState: FormikState) => FormikState)' 不可分配给类型 'FormikState | ((prevState: FormikState) => FormikState)'。类型 'FormikState' 不可分配给类型 'FormikState | ((prevState: FormikState) => FormikState)'。


此错误来自 ActivityDashboard.tsx

输入 '{ setEditMode: (editMode: boolean) => void; 标题:字符串;描述:字符串;类别:字符串;城市:字符串;场地:字符串;日期:字符串;}' 缺少类型“IProps”中的以下属性:值、错误、触摸、isSubmitting 和 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>
  );
};
1个回答

我认为这里有多个问题导致来自 TypeScript 编译器的令人困惑的消息:

  1. 首先,确保您的功能组件扩展了React.FC<Props>类型,以便 TypeScript 知道这是一个 React 组件:

    import * as React from 'react';
    
    export const ActivityForm : React.FC<IProps> = (props) => {
    ...
    
  2. 然后,您必须IProps使用包中FormikProps-type扩展您的-type formik,因为withFormik-method 仅接受其 props 从此类型扩展的 React 组件:

    import { FormikProps } from 'formik';
    
    interface MyFormValues {
      title: string;
      category: string;
      description: string;
    }
    
    interface IProps extends FormikProps<MyFormValues> {
      setEditMode(arg: boolean): void;
    }
    

您的最终代码应如下所示(确保将缺少的属性添加到MyFormValues界面中):

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;

这里还有一个带有最终代码的 CodeSandbox:https ://codesandbox.io/s/stackoverflow59057524-s9ouc?module =% 2Fsrc%2FActivityForm.tsx