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

Posted

技术标签:

【中文标题】如何通过打字稿在Formik中添加强类型字段?【英文标题】:How to add strongly typed field in Formik by typescript? 【发布时间】:2020-03-22 06:16:20 【问题描述】:

我尝试通过 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 类型中缺少'setEditMode' & FormikHelpers & FormikHandlers & FormikComputedProps & FormikRegistration & ...; & ...; ' 但在类型中是必需的 'IPops'.ts(2345) ActivityForm.tsx(7, 3): 'setEditMode' 被声明 在这里。


const ActivityForm: React.FunctionComponent 类型参数 'FunctionComponent' 不可分配给类型参数 '复合组件 & FormikState & FormikHelpers & FormikHandlers & FormikComputedProps & FormikRegistration & ...; >'。类型“功能组件”是 不可分配给类型 'FunctionComponent & FormikState & FormikHelpers & FormikHandlers & FormikComputedProps & FormikRegistration & ...; >'。 属性“propTypes”的类型不兼容。 键入'弱验证映射 | undefined' 不可分配给类型 'WeakValidationMap & FormikState & FormikHelpers & FormikHandlers & FormikComputedProps & FormikRegistration & ...; > |不明确的'。 类型“WeakValidationMap”不可分配给类型“WeakValidationMap & FormikState & FormikHelpers & FormikHandlers & FormikComputedProps & FormikRegistration & ...; >'。 属性“setFormikState”的类型不兼容。 输入 'Validator FormikState), cb?: (() => void) |未定义)=> 无效> | undefined' 不可赋值 输入 'Validator FormikState), cb?: (() => 无效)|未定义)=> 无效> |不明确的'。 输入 'Validator FormikState), cb?: (() => void) | undefined) => void>' 不可分配给类型 '验证器 FormikState), cb?: (() => 无效)|未定义)=> 无效>'。 键入'(f: FormikState | ((prevState: FormikState) => FormikState), cb?: (() => 无效)| undefined) => void' 不可分配给类型 '(f: 福米克州 | (((prevState: FormikState) => FormikState), cb?: (() => void) |未定义)=> 无效'。 参数“f”和“f”的类型不兼容。 输入'FormikState | ((prevState: FormikState) => FormikState)' 不是 可分配给类型 'FormikState | ((上一个状态: FormikState) => FormikState)'。 类型 'FormikState' 不可分配给类型 'FormikState | ((上一个状态: FormikState) => FormikState)'。 类型“FormikState”不可分配给类型“FormikState”.ts(2345) Peek 问题 没有可用的快速修复方法


此错误来自 ActivityDashboard.tsx

类型 ' setEditMode: (editMode: boolean) => void;标题:字符串; 描述:字符串;类别:字符串;城市:字符串;场地:字符串; 日期:字符串; ' 缺少类型中的以下属性 'IPops':值、错误、已触摸、isSubmitting 和 28 多个.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 编译器发出令人困惑的消息:

    首先,确保你的函数组件扩展了 React.FC&lt;Props&gt; 类型,以便 TypeScript 知道这是一个 React 组件:

    import * as React from 'react';
    
    export const ActivityForm : React.FC<IProps> = (props) => 
    ...
    

    然后您必须使用 formik 包中的 FormikProps-type 扩展您的 IProps-type,因为 withFormik-method 仅接受其 props 扩展自该类型的 React-components:

    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/***59057524-s9ouc?module=%2Fsrc%2FActivityForm.tsx

【讨论】:

以上是关于如何通过打字稿在Formik中添加强类型字段?的主要内容,如果未能解决你的问题,请参考以下文章

如何通过打字稿在Vue2中使用带有组合api的vue类组件

如何使用打字稿在表格的单元格中动态插入锚标记?

如何通过使用打字稿在 beforeEach 挂钩中安装 Vue 组件来干燥代码?

如何使用打字稿在angular2中获取设备显示的高度和宽度?

使用打字稿在reduce方法中使用扩展语法进行解构

如何使用打字稿在 gulp-angular-generator 中定义指令