DefinitelyTyped icon indicating copy to clipboard operation
DefinitelyTyped copied to clipboard

Express' has no exported member 'Multer'

Open george-norris-salesforce opened this issue 5 years ago • 42 comments

Express' has no exported member 'Multer'. How do you use this library?

import { Express } from 'express'; type FileObj = Express.Multer.File & { ...}

Express' has no exported member 'Multer'.

din you install the multer typings as well? npm install --save-dev @types/multer

danmana avatar Oct 05 '20 15:10 danmana

din you install the multer typings as well? npm install --save-dev @types/multer

I did. Didn't help

weeebdev avatar Mar 04 '21 08:03 weeebdev

I did. Didn't help

Can you give us a bit more detail?

  • package.json
  • imports
  • how you use it

Otherwise, all I can say is that it should work :)

danmana avatar Mar 04 '21 09:03 danmana

I was facing the same issue, but can get it to compile using:

import { Express, Request } from 'express';

// This is a hack to make Multer available in the Express namespace
import { Multer } from 'multer';

type File = Express.Multer.File;

const file: File = req.file;

In devDependencies

"@types/express": "~4.17.3",
"@types/multer": "~1.4.5",
"typescript": "~4.1.2"

evindunn avatar Mar 04 '21 15:03 evindunn

I'm encountering this issue too. Why is this made into a global declaration and not exported so we can explicitly import the types?

WulffHunter avatar Mar 05 '21 04:03 WulffHunter

I did. Didn't help

Can you give us a bit more detail?

  • package.json
  • imports
  • how you use it

Otherwise, all I can say is that it should work :)

controller

import { Express } from 'express';
import { FileInterceptor } from '@nestjs/platform-express';
...
@Post()
  @UseInterceptors(FileInterceptor('image'))
  uploadFile(
    @Req() request: Request,
    // Here is it
    @UploadedFile() file: Express.Multer.File
  ) {
    return this.fileUploadService.uploadFile(file);
  }

package.json

 "@types/multer": "^1.4.5",

It does compile successfully, uploading works etc, but vscode gives this error

weeebdev avatar Mar 06 '21 07:03 weeebdev


// This is a hack to make Multer available in the Express namespace
import { Multer } from 'multer';

Worked for me. Thanks

weeebdev avatar Mar 06 '21 07:03 weeebdev

// This is a hack to make Multer available in the Express namespace
import { Multer } from 'multer';

Worked for me. Thanks

I'm glad this works, but I have no idea why it's needed.

I'm also using nestjs and vscode, but for me it works without the extra import...

import { Post, UploadedFile, UseInterceptors } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';

@Post('upload-image')
  @UseInterceptors(FileInterceptor('file'))
  async uploadImage(
    @UploadedFile() file: Express.Multer.File,
  ): Promise<CdnFileDto> {
    return this.cdnService.uploadFile(file);
  }

perhaps the difference is that I don't import Express anywhere

danmana avatar Mar 12 '21 12:03 danmana

// This is a hack to make Multer available in the Express namespace
import { Multer } from 'multer';

Worked for me. Thanks

I'm glad this works, but I have no idea why it's needed.

I'm also using nestjs and vscode, but for me it works without the extra import...

import { Post, UploadedFile, UseInterceptors } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';

@Post('upload-image')
  @UseInterceptors(FileInterceptor('file'))
  async uploadImage(
    @UploadedFile() file: Express.Multer.File,
  ): Promise<CdnFileDto> {
    return this.cdnService.uploadFile(file);
  }

perhaps the difference is that I don't import Express anywhere

When I don't import Express it says that it doesn't know what is express.

import { FileInterceptor } from '@nestjs/platform-express';
...
@Post()
  @UseInterceptors(FileInterceptor('image'))
  uploadFile(
    @Req() request: Request,
    // Here is it
    @UploadedFile() file: Express.Multer.File
  ) {
    return this.fileUploadService.uploadFile(file);
  }

Cannot find namespace 'Express'.ts(2503)

weeebdev avatar Mar 14 '21 08:03 weeebdev

// This is a hack to make Multer available in the Express namespace
import { Multer } from 'multer';

Worked for me. Thanks

This worked for me as well but I'd like to avoid doing a hack. Is there any reason why this is happening? In my case the problem arises when using ts-node.

SirBernardPhilip avatar May 21 '21 15:05 SirBernardPhilip

I have added it in the types field of the compilerOptions in my tsconfig.json so it won't get removed as unused import from my ide.

{
  "compilerOptions": {
    ...
    "types": ["Multer"]
  },
  ...
}

gkTim avatar May 26 '21 06:05 gkTim

I had the same issue in nestjs but only during production build. Turns out, when I moved the @types/multer from devDependencies to dependencies it worked 🤷🏼‍♂️

DavidVaness avatar Jun 04 '21 10:06 DavidVaness

I have added it in the types field of the compilerOptions in my tsconfig.json so it won't get removed as unused import from my ide.

{
  "compilerOptions": {
    ...
    "types": ["Multer"]
  },
  ...
}

@gkTim keep in mind by doint it this why, all other global types that would be imported automatically won't this way except for Multer https://www.typescriptlang.org/tsconfig#types

DavidVaness avatar Jun 04 '21 10:06 DavidVaness

All you have to do is:

import { Express } from 'express';
import 'multer';

This way you will also avoid any eslint warns about Multer never being used.

roznik-navisys avatar Jul 22 '21 07:07 roznik-navisys

All you have to do is install it types yarn add @types/multer

This worked for me

iamnotstatic avatar Oct 07 '21 16:10 iamnotstatic

None of the above solutions worked for me. What did work however was calling the import something else:

import whatever from 'multer';

dan-klasson avatar Nov 16 '21 18:11 dan-klasson

This unexpected behavior is still present in all latest versions (NestJS, TypeScript, express, ...).

The correct way of doing it is to just add @types/multer to your dev dependencies.

In our team everything worked fine locally, without any imports and on the production server it threw the error.

It seems to be dependent on something about the environment.

import 'multer';

Did the trick for us and we preferred it, since it is the shortest solution.

One more thing to note: it can also help to move @types/multer from dev dependencies to dependencies. Why? Don't know.

CemYil03 avatar Jan 21 '22 22:01 CemYil03

For me it was just an "VS Code gone wild thing"

type this

import { Multer } from "multer";

then Ctrl + click on Multer to open the index.d.ts file and VS Code now learns that there is in fact Multer in Express Namespace :)

levansuper avatar Jan 25 '22 14:01 levansuper

I'm having the same problem, but weirder. The code did compile ok, but adding unrelated code breaks it.

So I guess from past experiences, that there's a circular dependency happening somewhere. I didn't manage to solve it yet.

gentunian avatar Feb 16 '22 14:02 gentunian

Fixed by running npm install -D @types/multer

robertsLando avatar Feb 28 '22 16:02 robertsLando

Our team had same issue, did the npm i -D @types/multer and it didn't fix. Turns out our local environment was running in Docker and the way it was set up wasn't recreating the node_modules on subsequent npm install {whatever}. So we had to delete the local container and rebuild. Just in case someone else is having the same issue :)

PeterCockcroft avatar Mar 11 '22 11:03 PeterCockcroft

import "multer";

...should be sufficient.

But I wonder if multer should even be messing around with express' declarations.

Consider:

import { Express } from "express";
let r: Express.Request;
const f = r.file.fieldname; // <-- Property 'file' does not exist on type 'Request'. ts(2339)

and

import { Express } from "express";
import "multer";
let r: Express.Request;
const f = r.file.fieldname; // <-- OK

...it feels pretty weird that Express.Request is changing depending on what else I import.

kibiz0r avatar Apr 13 '22 18:04 kibiz0r

For yarn user, I use this yarn add @types/multer -D

bombxdev avatar Jun 16 '22 04:06 bombxdev

clean, encapsuled, global

index.d.ts:

/* eslint-disable @typescript-eslint/no-empty-interface */
import { Multer as MulterNamed } from 'multer';

declare global {
    namespace Express {
        interface Multer extends MulterNamed {}
    }
}

dfenerski avatar Nov 03 '22 08:11 dfenerski

yarn add @types/multer -D and import multer; fixed it for me

sarunmrzn avatar Nov 15 '22 08:11 sarunmrzn

yarn add @types/multer -D and import multer; fixed it for me

This worked for me too. I actually, I did some inspection and found out that they're 03 namespaces declaration of Express.

  • @types/express-session
  • @types/multer
  • @types/passport To my understanding, Express from multer wasn't the priority so adding import 'multer' prioritize it over the others.

Marcjazz avatar Nov 20 '22 21:11 Marcjazz

yarn add @types/multer -D and import multer; fixed it for me

it works for me thanks

spielcrypto avatar Feb 15 '23 10:02 spielcrypto

Awesome.

QUDUSKUNLE avatar Feb 16 '23 14:02 QUDUSKUNLE

I was facing the same issue, but can get it to compile using:

import { Express, Request } from 'express';

// This is a hack to make Multer available in the Express namespace
import { Multer } from 'multer';

type File = Express.Multer.File;

const file: File = req.file;

In devDependencies

"@types/express": "~4.17.3",
"@types/multer": "~1.4.5",
"typescript": "~4.1.2"

This doesn't work for me because I have prettier. It keeps removing unused imports.

Here is mine

import type { Multer } from 'multer';
type File = Multer;

tawanorg avatar Apr 07 '23 03:04 tawanorg

"types": ["Multer"]

Perfect, this solved it for me.

viniciuslk avatar May 23 '23 21:05 viniciuslk