node.jstypescriptserverstoragemulter

Using multer diskStorage with Typescript


I'm translating a node.js server to typescript.

My funcion with node is:

const storage = multer.diskStorage({
    destination: function (req, file, cb) {
        const dir = './uploads/';
        mkdirp(dir, err => cb(err, dir));
    },
    filename: function (req, file, cb) {
        cb(null, file.originalname)
    }
});

const upload = multer({
    storage: storage
});

router.post('/test', upload.fields({name: 'image'}), async function (req, res, next) {
...
});

But I have a lot of errors. For example I can't set the file argument as Express.File type, 'memoryStorage' does not accept arguments or mkdirp tells me that is not callable.


Solution

  • Here's how I did it using the type definitions in the @types/multer.

    If you haven't already, first install the type definitions for the multer package:

    npm i --save-dev @types/multer
    

    Imports and type aliases

    import { Request } from 'express'
    import multer, { FileFilterCallback } from 'multer'
    
    type DestinationCallback = (error: Error | null, destination: string) => void
    type FileNameCallback = (error: Error | null, filename: string) => void
    

    For storage

    export const fileStorage = multer.diskStorage({
        destination: (
            request: Request,
            file: Express.Multer.File,
            callback: DestinationCallback
        ): void => {
            // ...Do your stuff here.
        },
    
        filename: (
            req: Request, 
            file: Express.Multer.File, 
            callback: FileNameCallback
        ): void => {
            // ...Do your stuff here.
        }
    })
    

    For fileFilter

    export const fileFilter = (
        request: Request,
        file: Express.Multer.File,
        callback: FileFilterCallback
    ): void => {
        if (
            file.mimetype === 'image/png' ||
            file.mimetype === 'image/jpg' ||
            file.mimetype === 'image/jpeg'
        ) {
            callback(null, true)
        } else {
            callback(null, false)
        }
    }
    

    For cleaner code and separation of concerns, place the above two constants in a separate file like config/multer.ts or util/multer.ts

    Usage

    Import and use the above constants in app.ts or server.ts:

    app.use(multer({ storage: fileStorage, fileFilter: fileFilter })