express-fileupload具有如下声明:
declare namespace fileUpload {
class FileArray {
[index: string]: UploadedFile | UploadedFile[]
}
interface UploadedFile {
name: string;
encoding: string;
mimetype: string;
data: Buffer;
truncated: boolean;
mv(path: string, callback: (err: any) => void): void;
mv(path: string): Promise<void>;
}
然后在控制器Iam中将其用作:
const file: UploadedFile | UploadedFile[] = req.files.file;
但是现在TypeScript的功能
Property 'name' does not exist on type 'UploadedFile | UploadedFile[]'.
Property 'name' does not exist on type 'UploadedFile[]'.
用于文件名
在数组类型中,没有原因。
tyo如何处理这种情景?尝试
if (file instanceof Array)
if (file typeof UploadedFile[])
但这不起作用。
答案 0 :(得分:2)
if (file typeof UploadedFile[])
部分将不起作用,因为typeof
是JS运行时检查,而UploadedFile[]
是一种类型。类型的概念在运行时并不真正存在,因此无法执行该语句。
但是首先检查file
是否为数组应该足够了。通过编写处理类型UploadedFile | UploadedFile[]
的代码,您基本上信任分配给该类型的变量,使其在运行时具有该类型的值。因此,如果它不是数组,则必须为UploadedFile
类型的值:
if (Array.isArray(req.files.file)) {
// It must be an array of UploadedFile objects...
} else {
// It must be a single UploadedFile object...
}
繁琐的部分是,只要变量具有这样的联合类型,就必须编写类似于if ...的结构,否则要在该变量上执行操作的任何地方(读取,转换,或以其他方式使用它)。有没有更清洁的方法?
您可以将file
的值规范化为始终为数组,然后始终将其视为这样
如果req.files.file
是一个数组,则将myFiles
设为req.files.file
。否则,使myFiles
为包含1个元素的数组,该元素为req.files.file
:
const myFiles: UploadedFile[] = Array.isArray(req.files.file)
? req.files.file
: [req.files.file];
现在考虑拥有一个功能handleSingleFile
,您必须为来自req.files.file
的所有文件运行该功能。不用写:
if (Array.isArray(req.files.file)) {
req.files.file.forEach((file) => handleSingleFile(file));
} else {
handleSingleFile(req.files.file);
}
...您知道myFiles
将始终是一个数组:
myFiles.forEach((file) => handleSingleFile(file));