admin管理员组

文章数量:1292618

The error message that I receive in the value part of formData.append(key, value);:

Argument of type 'unknown' is not assignable to parameter of type 'string | Blob'. Type '{}' is missing the following properties from type 'Blob': size, type, arrayBuffer, slice, and 2 more.

Code

const uploadSubtitle = async e => {
            e.preventDefault();
            const file = fileInput.current.files[0];
            const res = await Axios.get(`/api/movies/${currentMovie.movieId}/subtitles?user=${user.id}`);
            const { url, fields } = res.data;
            const newUrl = `https://${url.split('/')[3]}.s3.amazonaws`;
            const formData = new FormData();
            const formArray = Object.entries({ ...fields, file });
            formArray.forEach(([key, value]) => {
                formData.append(key, value);
            });
           //... further code
    };


<form onSubmit={uploadSubtitle}>
   <input type='file' name='subtitle' ref={fileInput} accept='.srt' />
   <button onClick={uploadSubtitle}>Upload</button>
</form>

Additional details

console.log(file) gives

File 
{name: "Trainspotting-English.srt", lastModified: 1587840529000, 
lastModifiedDate: Sun Apr 26 2020 00:18:49 GMT+0530 (India Standard Time), 
webkitRelativePath: "", size: 103040, …}

lastModified: 1587840529000 lastModifiedDate: Sun Apr 26 2020 00:18:49 GMT+0530 (India Standard Time) 
{} name: "Trainspotting-English.srt" size: 103040 
type: "application/x-subrip" webkitRelativePath: "" __proto__: File

console.log(typeof file) gives object

The error message that I receive in the value part of formData.append(key, value);:

Argument of type 'unknown' is not assignable to parameter of type 'string | Blob'. Type '{}' is missing the following properties from type 'Blob': size, type, arrayBuffer, slice, and 2 more.

Code

const uploadSubtitle = async e => {
            e.preventDefault();
            const file = fileInput.current.files[0];
            const res = await Axios.get(`/api/movies/${currentMovie.movieId}/subtitles?user=${user.id}`);
            const { url, fields } = res.data;
            const newUrl = `https://${url.split('/')[3]}.s3.amazonaws.`;
            const formData = new FormData();
            const formArray = Object.entries({ ...fields, file });
            formArray.forEach(([key, value]) => {
                formData.append(key, value);
            });
           //... further code
    };


<form onSubmit={uploadSubtitle}>
   <input type='file' name='subtitle' ref={fileInput} accept='.srt' />
   <button onClick={uploadSubtitle}>Upload</button>
</form>

Additional details

console.log(file) gives

File 
{name: "Trainspotting-English.srt", lastModified: 1587840529000, 
lastModifiedDate: Sun Apr 26 2020 00:18:49 GMT+0530 (India Standard Time), 
webkitRelativePath: "", size: 103040, …}

lastModified: 1587840529000 lastModifiedDate: Sun Apr 26 2020 00:18:49 GMT+0530 (India Standard Time) 
{} name: "Trainspotting-English.srt" size: 103040 
type: "application/x-subrip" webkitRelativePath: "" __proto__: File

console.log(typeof file) gives object

Share Improve this question edited Jan 19, 2021 at 12:26 lissettdm 13.1k1 gold badge23 silver badges42 bronze badges asked Jan 12, 2021 at 9:19 rohitmi0023rohitmi0023 1191 gold badge3 silver badges13 bronze badges 5
  • Have you tried casting file, or calling new Blob on it? – Zac Anger Commented Jan 17, 2021 at 17:56
  • @ZacAnger, I tried this.. const blob = new Blob([fileInput.current.files[0]]) and then this const formArray = Object.entries({ ...fields, file: blob });, still it gives me same error – rohitmi0023 Commented Jan 17, 2021 at 18:00
  • one thing that I would like to add is I am able to successfully upload files during developments...its just the typescript error that's causing the problem – rohitmi0023 Commented Jan 17, 2021 at 18:01
  • Yeah, the error is ing from TypeScript, so you just need to figure out the right way to trick it into being happy. a // @ts-ignore ment would work but it'd be better to figure out what it wants. Asserting that value is any would also work: formData.append(key, value as any), or const file = fileInput.current.files[0] as Blob maybe. – Zac Anger Commented Jan 17, 2021 at 18:06
  • the former one works i.e. doesn't plains about type error but the later doesn't...still I was wondering whether console.log(file) should already be Blob since the __proto__ is File of file. – rohitmi0023 Commented Jan 17, 2021 at 18:12
Add a ment  | 

2 Answers 2

Reset to default 5 +50

It all es down to the unknown type of res, introduced here:

const res = await Axios.get(`/api/movies/${currentMovie.movieId}/subtitles?user=${user.id}`);

res is any, which makes fields type any, which in turn makes formArray be of type [string, unknown][], thus value is unknown, which causes the error.

To solve this problem at the source, we can use a generic type on the Axios.get method like so:

const res = await Axios.get<{url :string, fields: {[key:string]:string}}>(`/api/movies/xxx/subtitles?user=xxx`);

This will make res be of type {url :string, fields: {[key:string]:string}}. This causes fields to be of type {[key:string]:string}.

Unfortunately the spread operator does not infer the right types. The code {...fields, file} resolves to type {file: File}, which is not really helpful. So let's hint formArray:

const formArray : [string, string|File][] = Object.entries({...fields, file});

Now value will be of type string|File.

Full example:

function App() {

    let fileInput = useRef<HTMLInputElement>(null);

    const uploadSubtitle = async (e: React.FormEvent) => {
        e.preventDefault();
        const file = fileInput.current!.files![0];
        const res = await Axios.get<{ url: string, fields: { [key: string]: string } }>(`/api/movies/xxx/subtitles?user=xxx`);
        const {url, fields} = res.data;
        const formData = new FormData();
        const formArray: [string, string | File][] = Object.entries({...fields, file});
        formArray.forEach(([key, value]) => {
            formData.append(key, value);
        });
    };
    return <form onSubmit={uploadSubtitle}>
        <input type='file' name='subtitle' ref={fileInput} accept='.srt'/>
        <button type="submit">Upload</button>
    </form>
}

This is all rather a lot of work for something that can be fixed by changing the problematic line to:

formData.append(key, value as Blob);

Adding the as Blob won't change the piled JS but will make the typescript piler stop plaining.

I had File data as { name: '', type: '', uri: ''} which was giving the error: Argument of type 'FileData' is not assignable to parameter of type String or Blob

So I did the following:

form.append('file', value as {} as Blob); TS stopped plaining.

本文标签: javascriptType error while uploading file using formDataStack Overflow