如何解决此打字稿承诺错误?

时间:2019-07-08 13:54:15

标签: reactjs typescript

我收到以下错误。我认为这与以前使用的新TS版本有关。

这是错误:

> Type error: Type 'Promise<{ content: unknown; fileName: string;
> contentType: string; length: number; }>[]' is not assignable to type
> 'Promise<Base64File>[]'.    Type '{ content: unknown; fileName:
> string; contentType: string; length: number; }' is not assignable to
> type 'Base64File'.
>       Types of property 'content' are incompatible.
>         Type 'unknown' is not assignable to type '{}'.  TS2322
>     152 |     const token = await this.props.googleReCaptchaProps.executeRecaptcha("CreateProfessionalUser");
>     153 | 
>   > 154 |     let files: Promise<Base64File>[] = Array.from(values.file).map(async file => ({
>         |         ^
>     155 |       content: await getBase64(file),
>     156 |       fileName: file.name,
>     157 |       contentType: file.type,

这是我的代码:

import * as React from "react";
import { useState } from 'react';
import { Row, Col } from "react-bootstrap";
import { Formik, Form, Field, ErrorMessage } from "formik";
import * as Yup from "yup";
import axios from "axios";

import Error from "../../Error/";

interface Base64File {
  content: {};
  fileName: string;
  contentType: string;
  length: number;
}

interface FormikBlob extends Blob {
  name: string;
}

type FormValues = {
  username: string;
  password: string;
  repeatPassword: string;
  clinicName: string;
  address: string;
  address2: string;
  zipCode: string;
  city: string;
  country: string;
  state: string;
  vatNumber: string;
  fullName: string;
  title: string;
  email: string;
  phone: string;
  website: string;
  file: FormikBlob[];
  acceptDeclarationOnHonor: string;
  acceptProfessionalConsent: string;
};



export default function CreateProfessionalUserForm(props: any) {

  const supportedFormats = ["image/jpg", "image/jpeg", "image/gif", "image/png"];

  function getBase64(file: FormikBlob) {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.readAsDataURL(file);
      reader.onload = _ => {
        var base64String = (reader.result as string).split(",").pop();
        resolve(base64String);
      };
      reader.onerror = e => reject(e);
    });
  }

  const [errorMessage, setErrorMessage] = useState();

  const createProfessionalAccountSchema = Yup.object().shape({
    username: Yup.string()
      .required("Required")
      .min(8, "Too Short!")
      .max(20, "Too Long!")
      .matches(/^[\w-.@ ]+$/, {
        message: "Inccorect carector"
      }),

    password: Yup.string()
      .required("Required")
      .min(10, "Too Short!")
      .max(100, "Too Long!")
      .matches(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^a-zA-Z\d\s:]).*$/, {
        message: "Password need to contain 1 uppercase character (A-Z), 1 lowercase character (a-z), 1 digit (0-9) and 1 special character (punctuation)"
      }),

    repeatPassword: Yup.string()
      .required("Required")
      .oneOf([Yup.ref("password")], "Passwords must match"),

    clinicName: Yup.string()
      .required("Required")
      .max(35, "Too Long!"),

    address: Yup.string()
      .required("Required")
      .max(35, "Too Long!"),

    address2: Yup.string().max(35, "Too Long!"),

    zipCode: Yup.string()
      .required("Required")
      .max(35, "Too Long!"),

    city: Yup.string()
      .required("Required")
      .max(100, "Too Long!"),

    state: Yup.string().max(100, "Too Long!"),

    fullName: Yup.string()
      .required("Required")
      .max(35, "Too Long!")
      .matches(/^.*?\S+[ ]\S+.*$/, {
        message: "Name must be 2 words or more"
      }),

    title: Yup.string()
      .required("Required")
      .max(35, "Too Long!"),

    email: Yup.string()
      .required("Required")
      .email("Invalid email")
      .max(50, "Too Long!"),

    phone: Yup.string()
      .required("Required")
      .max(15, "Too Long!")
      .matches(/^\+?\d+$/, {
        message: "Must only contain numbers"
      }),

    /*
      file: Yup.mixed()
      .test(
        "fileFormat",
        "Unsupported file Format",
        value => value && supportedFormats.includes(value.type)
      ),
      */

    acceptDeclarationOnHonor: Yup.string().required("Required"),

    acceptProfessionalConsent: Yup.string().required("Required")
  });



  function handleSuccess() {
    alert("User was created");
  }

  async function handleSubmit(values: FormValues) {
    const token = await props.googleReCaptchaProps.executeRecaptcha("CreateProfessionalUser");

    let files: Promise<Base64File>[] = Array.from(values.file).map(async file => ({
      content: await getBase64(file),
      fileName: file.name,
      contentType: file.type,
      length: file.size
    }));

    Promise.all(files)
      .then(async fileResult => {
        console.log(fileResult);

        const headers = {
          headers: {
            Accept: "application/json",
            "Content-Type": "application/json",
            recaptcha: token
          }
        };

        const body = {
          username: values.username,
          password: values.password,
          repeatPassword: values.repeatPassword,
          fullname: values.fullName,
          countryId: values.country,
          email: values.email,
          title: values.title,
          clinicName: values.clinicName,
          address1: values.address,
          address2: values.address2,
          postCode: values.zipCode,
          city: values.city,
          state: values.state,
          phone: values.phone,
          website: values.website,
          vatNumber: values.vatNumber,
          files: fileResult
        };

        const url = "xxx";

        try {
          const response = await axios.post(url, body, headers);
          if (response.status === 201) {
            handleSuccess();
          }
          if (response.status === 400) {
            console.log("Bad Request ...");
            setErrorMessage('Bad Request');
          } else if (response.status === 409) {
            console.log("Conflict ...");
            setErrorMessage('Conflict');
          } else if (response.status === 422) {
            console.log("Client Error ...");
            setErrorMessage('Client Error');
          } else if (response.status > 422) {
            console.log("Something went wrong ...");
            setErrorMessage('Something went wrong');
          } else {
            console.log("Server Error ...");
            setErrorMessage('Server Error');
          }
        } catch (e) {
          console.log("Fejl");
        }
      })
      .catch(error => {
        console.log(error);
      });
  }



  return (
    <React.Fragment>
      <Row>
        <Col xs={12}>
          <p>
            If you are an approved tissue center, a fertility clinic, a hospital department or an authorized healthcare professional in your home country, please create a Professional account. You
            must provide documentation in form of a license or authorization before we can ship orders.
            </p>
        </Col>
      </Row>
      <Row>
        <Col xs={12}>
          <Formik
            initialValues={{
              username: "",
              password: "",
              repeatPassword: "",
              clinicName: "",
              address: "",
              address2: "",
              zipCode: "",
              city: "",
              country: "",
              state: "",
              vatNumber: "",
              fullName: "",
              title: "",
              email: "",
              phone: "",
              website: "",
              file: [],
              acceptDeclarationOnHonor: "",
              acceptProfessionalConsent: ""
            }}
            validationSchema={createProfessionalAccountSchema}
            onSubmit={async (values, { setErrors, setSubmitting }) => {
              await handleSubmit(values);
              setSubmitting(false);
            }}>
            {({ isSubmitting, setFieldValue }) => (
              <Form>
                {errorMessage ? <Error errorMessage={errorMessage} /> : null}
                <Row>
                  <Col xs={6}>
                    <Row>
                      <Col xs={12}>
                        <label htmlFor='username'>Username:</label>
                        <Field type='text' name='username' />
                        <ErrorMessage name='username'>{msg => <div className='error'>{msg}</div>}</ErrorMessage>
                      </Col>
                    </Row>
                    <Row>
                      <Col xs={12}>
                        <label htmlFor='password'>Password:</label>
                        <Field type='password' name='password' />
                        <ErrorMessage name='password'>{msg => <div className='error'>{msg}</div>}</ErrorMessage>
                      </Col>
                    </Row>
                    <Row>
                      <Col xs={12}>
                        <label htmlFor='repeatPassword'>Repeat password:</label>
                        <Field type='password' name='repeatPassword' />
                        <ErrorMessage name='repeatPassword'>{msg => <div className='error'>{msg}</div>}</ErrorMessage>
                      </Col>
                    </Row>
                  </Col>
                  <Col xs={6}>
                    <Row>
                      <Col xs={12}>
                        <label htmlFor='fullName'>Full name:</label>
                        <Field type='text' name='fullName' />
                        <ErrorMessage name='fullName'>{msg => <div className='error'>{msg}</div>}</ErrorMessage>
                      </Col>
                    </Row>
                    <Row>
                      <Col xs={12}>
                        <label htmlFor='title'>Title:</label>
                        <Field type='text' name='title' />
                        <ErrorMessage name='title'>{msg => <div className='error'>{msg}</div>}</ErrorMessage>
                      </Col>
                    </Row>
                    <Row>
                      <Col xs={12}>
                        <label htmlFor='email'>E-mail:</label>
                        <Field type='email' name='email' />
                        <ErrorMessage name='email'>{msg => <div className='error'>{msg}</div>}</ErrorMessage>
                      </Col>
                    </Row>
                  </Col>
                </Row>
                <Row>
                  <Col xs={6}>
                    <Row>
                      <Col xs={12}>
                        <label htmlFor='clinicName'>Clinic name:</label>
                        <Field type='text' name='clinicName' />
                        <ErrorMessage name='clinicName'>{msg => <div className='error'>{msg}</div>}</ErrorMessage>
                      </Col>
                    </Row>
                    <Row>
                      <Col xs={12}>
                        <label htmlFor='address'>Address:</label>
                        <Field type='text' name='address' />
                        <ErrorMessage name='address'>{msg => <div className='error'>{msg}</div>}</ErrorMessage>
                      </Col>
                    </Row>
                    <Row>
                      <Col xs={12}>
                        <label htmlFor='address2'>Address 2:</label>
                        <Field type='text' name='address2' />
                        <ErrorMessage name='address2'>{msg => <div className='error'>{msg}</div>}</ErrorMessage>
                      </Col>
                    </Row>
                    <Row>
                      <Col xs={12}>
                        <label htmlFor='zipCode'>Zip Code:</label>
                        <Field type='text' name='zipCode' />
                        <ErrorMessage name='zipCode'>{msg => <div className='error'>{msg}</div>}</ErrorMessage>
                      </Col>
                    </Row>
                    <Row>
                      <Col xs={12}>
                        <label htmlFor='city'>City:</label>
                        <Field type='text' name='city' />
                        <ErrorMessage name='city'>{msg => <div className='error'>{msg}</div>}</ErrorMessage>
                      </Col>
                    </Row>
                    <Row>
                      <Col xs={12}>
                        <label htmlFor='country'>Country:</label>
                        <Field component='select' name='country'>
                          <option value=''>Select Country</option>
                          <option value='56'>Denmark</option>
                        </Field>
                        <ErrorMessage name='country' component='div' />
                      </Col>
                    </Row>
                    <Row>
                      <Col xs={12}>
                        <label htmlFor='state'>State/Region:</label>
                        <Field type='text' name='state' />
                        <ErrorMessage name='state'>{msg => <div className='error'>{msg}</div>}</ErrorMessage>
                      </Col>
                    </Row>
                    <Row>
                      <Col xs={12}>
                        <label htmlFor='vatNumber'>VAT number:</label>
                        <Field type='text' name='vatNumber' />
                        <ErrorMessage name='vatNumber'>{msg => <div className='error'>{msg}</div>}</ErrorMessage>
                      </Col>
                    </Row>
                  </Col>
                  <Col xs={6}>
                    <Row>
                      <Col xs={12}>
                        <label htmlFor='phone'>Phone:</label>
                        <Field type='text' name='phone' />
                        <ErrorMessage name='phone'>{msg => <div className='error'>{msg}</div>}</ErrorMessage>
                      </Col>
                    </Row>
                    <Row>
                      <Col xs={12}>
                        <label htmlFor='website'>Website:</label>
                        <Field type='text' name='website' />
                        <ErrorMessage name='website'>{msg => <div className='error'>{msg}</div>}</ErrorMessage>
                      </Col>
                    </Row>
                  </Col>
                </Row>

                <Row>
                  <Col xs={12}>
                    <label htmlFor='file'>File:</label>
                    <input
                      id='file'
                      name='file'
                      type='file'
                      onChange={event => {
                        //setFieldValue("file", event.currentTarget.files[0]);
                        setFieldValue("file", event.currentTarget.files);
                      }}
                      multiple
                    />
                    <ErrorMessage name='file'>{msg => <div className='error'>{msg}</div>}</ErrorMessage>
                  </Col>
                </Row>

                <Row>
                  <Col xs={12}>
                    <label htmlFor='acceptDeclarationOnHonor'>
                      <Field type='checkbox' name='acceptDeclarationOnHonor' />I hereby declare that my identity is as I have stated Declaration of honor
                      </label>
                    <ErrorMessage name='acceptDeclarationOnHonor'>{msg => <div className='error'>{msg}</div>}</ErrorMessage>
                  </Col>
                </Row>

                <Row>
                  <Col xs={12}>
                    <label htmlFor='acceptProfessionalConsent'>
                      <Field type='checkbox' name='acceptProfessionalConsent' />I have been informed about how Cryos processes my personal data in Cryos’ Privacy Policy
                      </label>
                    <ErrorMessage name='acceptProfessionalConsent'>{msg => <div className='error'>{msg}</div>}</ErrorMessage>
                  </Col>
                </Row>

                <Row>
                  <Col xs={12}>
                    <button type='submit' disabled={isSubmitting}>
                      Create User
                      </button>
                  </Col>
                </Row>
              </Form>
            )}
          </Formik>
        </Col>
      </Row>
    </React.Fragment>
  );
}

1 个答案:

答案 0 :(得分:0)

错误源于Base64File.contentunknown不兼容的事实。因此,您可以更改以下内容:

interface Base64File {
  content: {};
  fileName: string;
  contentType: string;
  length: number;
}

对此:

interface Base64File {
  content: unknown; // or 'content: any'
  fileName: string;
  contentType: string;
  length: number;
}