我在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}`);
res
是any
,这使得fields
是any
类型,这又使得formArray
是[string, unknown][]
类型,因此value
是unknown
,这导致了错误。
为了从源头上解决这个问题,我们可以在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编译器停止抱怨。