I am migrating from JS to TS and encountering some issues along the way. I'm using the widely known multer package with a custom storage engine multer-s3 to efficiently stream incoming files directly to AWS.
The custom storage engine, multer-s3, thereby provides its own definition of the "file" property which extends multer's definition. multer-s3's index.d.ts
file looks like this (multer-s3's full type definitions can be found 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;
}
}
}
}
Whenever I'm parsing incoming files though, multer uses its own definition of File rather than multer-s3's definition, which causes properties, like location
, to be unavailable on the req.file
object.
My question now: how can I get multer to work with multer-s3's file definition rather than its own? Prior to migrating to typescript, all of the properties contained in multer-s3's type definitions for "File" were accessible under req.file
- unfortunately, typescript doesn't recognize that. So far I'm somehow using a workaround by creating a new property on my request interface of type Express.MulterS3.File
:
export default interface IRequest extends express.Request {
processedFile?: Express.MulterS3.File;
}
And then, inside the parsing middleware, cast down the req.file
property to Express.MulterS3.File
, which makes the needed properties available:
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);
}
};
However, I'm not sure if that's the right way to do it and would kindly like to ask for your help on this issue. My goal is to simply have req.file
be of type Express.MulterS3.File
rather than Express.Multer.File
.
Maybe some of you know where the issue lies or encountered it themselves when working with multer-s3 & multer in typescript. Any help would be greatly appreciated!