Multer: Typescript: Property 'file' does not exist on type 'Request'

Created on 2 May 2016  路  10Comments  路  Source: expressjs/multer

Because the file/s or body attributes (and all the rest) is added in runtime, the Typescript compiler does not recognize them and it fails. So, they should be referenced like this

app.post('/profile', upload.single('avatar'), function (req, res, next) {
  // req['file'] is the `avatar` file
  // req['body'] will hold the text fields, if there were any
})

app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {
  // req['files'] is array of `photos` files
  // req['body'] will contain the text fields, if there were any
})

Just wanted to point that out. Maybe you can add a comment in the documentation.
Thanks!

Most helpful comment

I haven't been writing them, but I could. I just have a simple local definition for myself that looks like this:

export interface MulterFile {
  key: string // Available using `S3`.
  path: string // Available using `DiskStorage`.
  mimetype: string
  originalname: string
  size: number
}

app.get(function (req: express.Request & { files: MulterFile[] }, res: express.Response) {})

I'd be happy to formalise this more and put them here for everyone to use.

All 10 comments

Hmm, this is a though one, I don't know if there is any way to let TypeScript know about the middlewares and the fields that it tacks on to req. If anyone has any experience with this I would be happy to hear some insight...

Yes, I agree. I don't think there is a way either. For the moment this is how I solved it...

@nmobregon Can you point out the definitions you're currently using. Is it correct that your fix is the square brackets? In which case, I believe that'll break once you use noImplicitAny - instead you should be using module augmentation to augment the request object with multer compatible additions that you then make stricter in the middleware itself. I'll understand if that makes no sense, but something like:

declare module 'express' {
  interface Request {
    body: any // Actually should be something like `multer.Body`
    files: any // Actually should be something like `multer.Files`
  }
}

function (req: express.Request, res: express.Response, next: express.NextFunction) {
  req.body // Now valid, but we can make it better when we know the exact type. E.g. `req.body as multer.MoreAccurateBodyType`.
}

This is actually easy enough to achieve, but there's no way to make it strongly typed (you'd just have to tell the compiler what it looks like instead).

Since this isn't really to do with the module, there's no documented TypeScript support that I saw, I'm not sure what would be documented about it.

Edit: FWIW, I'd be happy to do a PR and get a good definition into the repo with instructions on how to use it properly. The currently DefinitelyTyped definitions aren't particularly great and are tightly coupled with their Express.js definition.

Edit 2: @nmobregon did you install the multer definitions?

FWIW, I'd be happy to do a PR and get a good definition into the repo with instructions on how to use it properly. The currently DefinitelyTyped definitions aren't particularly great and are tightly coupled with their Express.js definition.

That would be awesome 馃檶 I would be happy to accept a pull request for that!

Well, thanks for your answers. I want to apologise because I was having some permissions issues and so my tsc wasn't being able to access the multer definition file. Now it's working and it recognizes the new properties.
I'll follow the module augmentation concept to add some properties I need for my app.
Guess I should close this issue.
Thanks again!

I am facing the same issue. How did you fix this ?

@blakeembrey Hey, have there been any updates to the typings definitions? Facing the same issue. Workaround suggested by @nmobregon works but isn't ideal.

I haven't been writing them, but I could. I just have a simple local definition for myself that looks like this:

export interface MulterFile {
  key: string // Available using `S3`.
  path: string // Available using `DiskStorage`.
  mimetype: string
  originalname: string
  size: number
}

app.get(function (req: express.Request & { files: MulterFile[] }, res: express.Response) {})

I'd be happy to formalise this more and put them here for everyone to use.

I'm all for it! Having that in there by default would avoid a lot of confusion.

Install the type definitions for multer.

bash npm install --save @types/multer

Was this page helpful?
0 / 5 - 0 ratings