我收到以下错误。我认为这与以前使用的新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>
);
}
答案 0 :(得分:0)
错误源于Base64File.content
和unknown
不兼容的事实。因此,您可以更改以下内容:
interface Base64File {
content: {};
fileName: string;
contentType: string;
length: number;
}
对此:
interface Base64File {
content: unknown; // or 'content: any'
fileName: string;
contentType: string;
length: number;
}