如何对 req.file 使用 multer-s3 的类型定义而不是 multer 的

问题描述 投票:0回答:2

我正在从 JS 迁移到 TS,并在此过程中遇到了一些问题。我使用广为人知的 multer 包和自定义存储引擎 multer-s3 来高效地将传入文件直接流式传输到 AWS。

自定义存储引擎 multer-s3 提供了自己的“文件”属性定义,扩展了 multer 的定义。 multer-s3 的

index.d.ts
文件如下所示(multer-s3 的完整类型定义可以在 here 找到):

declare global {
    namespace Express {
        namespace MulterS3 {
            interface File extends Multer.File {
                bucket: string;
                key: string;
                acl: string;
                contentType: string;
                contentDisposition: null;
                storageClass: string;
                serverSideEncryption: null;
                metadata: any;
                location: string;
                etag: string;
            }
        }
    }
}

每当我解析传入文件时,multer 都会使用自己的 File 定义,而不是 multer-s3 的定义,这会导致

location
等属性在
req.file
对象上不可用。

我现在的问题:如何让 multer 使用 multer-s3 的文件定义而不是它自己的文件定义?在迁移到 Typescript 之前,multer-s3 的“文件”类型定义中包含的所有属性都可以在

req.file
下访问 - 不幸的是,Typescript 无法识别这一点。到目前为止,我正在使用一种解决方法,在类型为
Express.MulterS3.File
:

的请求接口上创建一个新属性
export default interface IRequest extends express.Request {
  processedFile?: Express.MulterS3.File;
}

然后,在解析中间件内部,将

req.file
属性向下转换为
Express.MulterS3.File
,这使得所需的属性可用:

export const acceptProfilePicUpload = async function (
  req: IRequest,
  res: express.Response,
  next: express.NextFunction
) {
  try {
    await new Promise((resolve, reject) => {
      multerUpload(req, res, (err: any) => {
        if (err) reject(err);
        else resolve(true);
      });
    });

    if (!req.file)
      throw new Error("file missing");

    req.processedFile = req.file as Express.MulterS3.File; // this is how I get TS to user multer-s3's type definitions - is there a better solution?    

    next();
  } catch (error) {
    console.log(error);
    next(error);
  }
};

但是,我不确定这是否是正确的方法,并恳请您就这个问题提供帮助。我的目标是简单地让

req.file
成为
Express.MulterS3.File
类型,而不是
Express.Multer.File

也许你们中的一些人知道问题出在哪里,或者在打字稿中使用 multer-s3 和 multer 时自己遇到过。 任何帮助将不胜感激!

node.js typescript amazon-s3 multer multer-s3
2个回答
0
投票

我修复了合并类型

Express.Multer.File
Express.MulterS3.File
的问题。

首先,您必须覆盖

Express.Request.file
中的
express
类型。您可以使用
typeRoots
中的
tsconfig.json
键来完成此操作。键接收一个字符串数组,每个字符串必须是一个指定文件夹的路径,其作用类似于
./node_modules/@types
。使用此键,您将能够覆盖
express
或任何其他库中的类型。

这是我的

typeRoots

"typeRoots": [
      "./node_modules/@types",
      "./src/@types"
],

然后,使用您的

Express.Request.file
声明创建一个文件,例如,这是我的
express.d.ts
(该文件可以有任何名称):

declare namespace Express {
  export interface Request {
    file: Express.Multer.File & Express.MulterS3.File;
  }
}

如果你想只改变

req.file
的类型而不是两者,你可以写:
Express.MulterS3.File



0
投票
declare namespace Express { export interface Request { file: Express.MulterS3.File; } }

的类型专门更改为

req.file
,您可以将以下代码添加到您的
Express.MulterS3.File
文件中:
express.d.ts

这将有效地使用 
declare global { namespace Express { namespace Multer { interface File { bucket: string; key: string; acl: string; contentType: string; contentDisposition: null; storageClass: string; serverSideEncryption: null; metadata: any; location: string; etag: string; } } } }

的属性覆盖

Express.Multer.File
类型,允许您在处理上传的文件时在 TypeScript 代码中使用 S3 特定的属性。
    

© www.soinside.com 2019 - 2024. All rights reserved.