使用formData上载文件时键入错误



我在formData.append(key, value);:的value部分中收到的错误消息

类型为"unknown"的参数不可分配给类型为的参数'string|Blob'。类型"{}"缺少中的以下属性type"Blob":size、type、arrayBuffer、slice和2个以上。

代码

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.com`;
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>

的其他详细信息

console.log(file)给出

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)给出object

这一切都归结为未知类型的res,在这里介绍:

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

resany,这使得fieldsany类型,这又使得formArray[string, unknown][]类型,因此valueunknown,这导致了错误。

为了从源头上解决这个问题,我们可以在Axios.get方法上使用一个泛型类型,如下所示:

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

这将使res成为{url :string, fields: {[key:string]:string}}类型。这使得fields的类型为{[key:string]:string}

不幸的是,排列运算符无法推断正确的类型。代码{...fields, file}解析为类型{file: File},这并没有真正的帮助。因此,让我们提示formArray:

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

现在value将是string|File类型。

完整示例:

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>
}

这是一项相当多的工作,可以通过将有问题的行更改为:来解决

formData.append(key, value as Blob);

添加as Blob不会改变已编译的JS,但会使typescript编译器停止抱怨。

相关内容

最新更新