D
D
dark_king_132020-05-01 06:18:42
typescript
dark_king_13, 2020-05-01 06:18:42

How to correctly set types for Formik in conjunction with Typescript?

I'm trying to build a non-React Typescript registration form using Formik.

Project Structure
5eab93c655128573435070.png

components/RegisterForm.tsx
import React from 'react'
import { MailOutlined, UserOutlined, LockOutlined, InfoCircleTwoTone } from '@ant-design/icons'
import { Form, Input } from 'antd'
import { Link } from "react-router-dom"
import {
  InjectedFormikProps,
  FormikHandlers,
  FormikTouched,
  FormikErrors,
} from 'formik';

import { Block, Button } from 'components'

interface RegisterFormPropsTypes {
  values          : {
    email         : string,
    fullname      : string,
    confirmed     : string,
    password      : string, 
  },
  touched         : FormikTouched<{
    email         : string
    fullname      : string
    password      : string
    confirmed     : string
  }>,
  errors          : FormikErrors<{
    email: string
    fullname: string
    password: string
    confirmed: string
  }>,
  handleChange    : FormikHandlers,
  handleBlur      : FormikHandlers,
  handleSubmit    : FormikHandlers,
  isValid         : any,
  isSubmitting    : any,
}

interface RegisterFormValuesTypes {
  email           : string,
  fullname        : string,
  password        : string,
  confirmed       : string
}

const success = false

const RegisterForm : React.FC<InjectedFormikProps<RegisterFormPropsTypes, RegisterFormValuesTypes>> = ({
  values,
  touched,
  errors,
  handleChange,
  handleBlur,
  handleSubmit,
  isValid,
  isSubmitting
}) => (
  <div>
    <div className="auth__top">
      <h2>Регистрация</h2>
      <p>Для входа в чат, вам нужно зарегистрироваться</p>
    </div>
    <Block>
      {!success ? (
      <Form className="login-form">
        <Form.Item
          validateStatus={
            !touched.email ? "" : errors.email ? "error" : "success"
          }
          help={!touched.email ? "" : errors.email}
          hasFeedback
        >
          <Input
            id="email"
            prefix={
              <MailOutlined />
            }
            size="large"
            type="text"
            placeholder="Email"
            value={values.email}
            onChange={handleChange}
            onBlur={handleBlur}
          />
        </Form.Item>
        <Form.Item
          validateStatus={
            !touched.fullname ? "" : errors.fullname ? "error" : "success"
          }
          help={!touched.fullname ? "" : errors.fullname}
          hasFeedback
        >
          <Input
            id="fullname"
            prefix={
              <UserOutlined />
            }
            size="large"
            type="text"
            placeholder="Ваше имя"
            value={values.fullname}
            onChange={handleChange}
            onBlur={handleBlur}
          />
        </Form.Item>
        <Form.Item
          validateStatus={
            !touched.password ? "" : errors.password ? "error" : "success"
          }
          help={!touched.password ? "" : errors.password}
          hasFeedback
        >
          <Input
            id="password"
            prefix={
              <LockOutlined />
            }
            size="large"
            type="password"
            placeholder="Пароль"
            value={values.password}
            onChange={handleChange}
            onBlur={handleBlur}
          />
        </Form.Item>
        <Form.Item
          validateStatus={
            !touched.confirmed ? "" : errors.confirmed ? "error" : "success"
          }
          help={!touched.confirmed ? "" : errors.confirmed}
          hasFeedback
        >
          <Input
            id="confirmed"
            prefix={
              <LockOutlined />
            }
            size="large"
            type="password"
            placeholder="Подтвердить пароль"
            value={values.confirmed}
            onChange={handleChange}
            onBlur={handleBlur}
          />
        </Form.Item>
        <Form.Item>
          {isSubmitting && !isValid && <span>Ошибка!</span>}
          <Button type="primary" size="large">
            Зарегистрироваться
          </Button>
        </Form.Item>
        <Link className="auth__register-link" to="/login">
          Войти в аккаунт
        </Link>
      </Form>
      ) : (
        <div className="auth__success-block">
          <div>
            <InfoCircleTwoTone />
          </div>
          <h2>Подтвердите свой аккаунт</h2>
          <p>
            На Вашу почту отправлено письмо с ссылкой на подтверждение
            аккаунта.
          </p>
        </div>
      )}
    </Block>
  </div>
)

export default RegisterForm

containers/RegisterForm.ts
import { withFormik } from 'formik'
import { default as RegisterForm } from '../components/RegisterForm'

export default withFormik({
  enableReinitialize: true,

  mapPropsToValues: () => ({
    email       : "",
    fullname    : "",
    password    : "",
    confirmed   : ""
  }),

  validate: values => {
    let errors = {
      email     : "",
      fullname  : "",
      password  : "",
      confirmed  : "",
    }

    if (!values.email) errors.email = "Введите email"
    else if (
      !/^[A-Z0-9._%+-][email protected][A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email)
    ) errors.email = "Некоректный email адрес"

    if (!values.fullname) errors.fullname = "Введите имя"
    else if (
      values.fullname.length <= 3
    ) errors.fullname = "Слишком короткое имя"

    if (!values.password) errors.password = "Введите пароль"
    else if (
      !/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.{8,})/.test(values.password)
    ) errors.password = "Слишком лёгкий пароль"

    if (!values.confirmed) errors.confirmed = "Повторите пароль"
    else if (values.confirmed !== values.password) errors.confirmed = "Пароли не совпадают"
    else if (
      !/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.{8,})/.test(values.confirmed)
    ) errors.confirmed = "Слишком лёгкий пароль"

    return errors
  },

  handleSubmit: (values, { setSubmitting }) => {
    setTimeout(() => {
      alert(JSON.stringify(values, null, 2))
      setSubmitting(false)
    }, 1000)
  },

  displayName: "RegisterForm"
})(RegisterForm)

And I get these errors:
error
5eab94472c6fb206126938.png

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question