首页 > 解决方案 > Typescript 如何处理类型或类型数组

问题描述

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

然后在控制器中将其用作:

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[]'.

对于文件名

因为在数组类型中没有属性“名称”。

你如何处理这种情况?一试

if (file instanceof Array)
if (file typeof UploadedFile[])

但这不起作用。

标签: typescripttypes

解决方案


if (file typeof UploadedFile[])部分将不起作用,因为typeof它是 JS 运行时检查,并且UploadedFile[]是一种类型。类型的概念在运行时并不真正存在,因此不可能执行该语句。

但是第一次检查是否file是一个数组实际上应该足够了。通过编写处理该类型的代码,UploadedFile | UploadedFile[]您基本上可以信任分配该类型的任何变量在运行时具有该类型的值。因此,如果它不是数组,则它必须是 type 的值UploadedFile

if (Array.isArray(req.files.file)) {
    // It must be an array of UploadedFile objects...
} else {
    // It must be a single UploadedFile object...
}

繁琐的部分是,只要变量具有这样的联合类型,您就必须编写类似于 if...else 的构造,以便对变量执行操作(读取、转换或以其他方式使用)它)。有没有更清洁的方法?

您可以将 的值标准化file为始终为数组,然后始终将其视为

如果是req.files.file一个数组,让. 否则,设一个包含 1 个元素的数组,即:myFilesreq.files.filemyFilesreq.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));

推荐阅读