Employing Multer and Express in conjunction with TypeScript

Overview

Currently, I am working on a project that involves creating a user-friendly website where individuals can easily upload images. For this particular task, I have employed Node.js, React, Multer, and Typescript.

Issue at Hand

app.post('/admin/uploads', async (req, res) => {
  uploadHandler(req, res, (err) => {
    ...
    if ( req.files.companyImage !== undefined ) {
      ...
    }
    res.sendStatus(201);
  });
});

An error is being highlighted by the TypeScript intellisense tool with regards to the 'companyImage' property within the 'files' object.

The specific error message reads as follows:

Property 'companyImage' does not exist on type '{ [fieldname: string]: File[]; } | File[]'.
Property 'companyImage' does not exist on type '{ [fieldname: string]: File[]; }'.ts(2339)

I find this perplexing since, in my understanding, the 'files' object should have a type of '{ [fieldname: string]: File[]; }'. This suggests that the 'files' object is capable of having properties that are strings.

To verify this hypothesis, I conducted a simple test:

Type myType = {
  [fieldName: string]: number
}

let req: myType = {
  a: 333,
  b: 344
}

console.log(req.a);
console.log(req.c); // The output is 'undefined', yet no errors are shown by intellisense.

Despite my analysis, I am still puzzled by why the 'companyImage' property cannot be present within the 'files' object.

If you could provide some clarification on this matter, it would be greatly appreciated.

Answer №1

It's uncertain if you have successfully resolved your problem, but I encountered a similar issue and had to explicitly declare the type of my req.files property in TypeScript as follows:

const files = req.files as { [fieldname: string]: Express.Multer.File[] };

It's important to note that when using upload.fields(...), I did not specify that req.files could also be a simple Express.Multer.File[].

Answer №2

To utilize typescript effectively, it's recommended to define an interface for files in the following manner:

interface IFile {
  fieldname: string;
  originalname: string;
  encoding: string;
  mimetype: string;
  buffer: Buffer;
  size: number;
}

After defining the interface, you can then assign

const files = req.files as IFile[]
. Ensure to include files: IFile; in the types/express/index.d.ts file like so:

declare global {
  namespace Express {
    interface Request {
      files: IFile;
    }
  }
}

Answer №3

On my TypeScript version (^5.2.2), I encountered a similar issue. Although there seems to be no type for Multer, I managed to resolve the problem.

To address this, I defined a namespace in a global type file:

export type IFile = {
  fieldname: string;
  originalname: string;
  encoding: string;
  mimetype: string;
  buffer: Buffer;
  size: number;
};

declare global {
  namespace Express {
    type Request = {
      files: IFile;
    };
  }
}

Next, I utilized the declared type where necessary:

const fileInfo = (req.files as { fileName?: IFile[] })['fileName']?.[0];

In this context, the variable fileName holds the name of your uploaded file.

Answer №4

The issue was resolved using the Object.assign(req.files) method, allowing it to be manipulated as an object: console.log(s.image[0].path);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is it advisable to exclude passport.js from gitignore along with Node?

While working on implementing user authentication, I followed a tutorial provided by Scotch.io. The tutorial included a passport.js file in the config directory that contained authentication tokens and database login information. I understand the importa ...

Outdated Vertx Crossing AuthorizedChoices

I successfully exposed the Vert.x EventBus through a socket based on the official documentation: The goal is to communicate with a NodeJS application. Initial tests have shown that messages are effectively passing between normal Verticals and the Node app ...

Exploring the differences between Angular's @Input and @Output directives and utilizing Injectable Services

When considering the differences between @Input/@Output in parent and child components versus using services that are instantiated only once with dependency injection (@Injectable()), I find myself questioning whether there are any distinctions beyond the ...

What is the best way to ensure that GCM push notifications are still received even when the app is closed or the

Currently, I'm in the process of developing an application using Ionic 2 that requires push notifications to be received. In certain scenarios, such as when the app is force-stopped on Android or when the device is turned off, push notifications are ...

Exploring the principles of object-oriented design within the context of Node

I am facing challenges with the asynchronous flow of Node.js. Let's assume we have the following class: function myClass() { var property = 'something'; var hasConnected = false; this.connect = function(params) { // Logic to conn ...

What causes req.body to be null after using event.preventDefault() in conjunction with fetch api, express, and node.js?

Is there a way to submit a form without causing the page to reload and still retrieve an object from MongoDB using server side scripts? I've tried preventing the default behavior of the form with an event handler to avoid the page refresh, but this ca ...

Transform the IO type to an array of Either in functional programming with the fp-ts

Looking for assistance with implementing this in fp-ts. Can someone provide guidance? const $ = cheerio.load('some text'); const tests = $('table tr').get() .map(row => $(row).find('a')) .map(link => link.attr(&apos ...

Node.js and Angular.js communication: from requests to responses

Efforts are being made to solicit data from a node.js server through angular.js. However, an unexpected challenge persists: post-data response, a stark white browser screen shows up with the JSON object in plain sight. The goal is for angular.js to acknowl ...

Every second, a PUT request is dispatched to the nearby database

I am currently in the process of developing software similar to a point-of-sale system for a restaurant. When an order is taken, it gets stored in a file called orderInQueue.json. Within the navigation menu, there is a tab labeled “Queued Orders” that ...

Discovering a search result from a pair of collections

I have a question regarding retrieving studentid from params and querying the Registration model to find registration information based on both the studentID and courseID. Once I have this information, I need to further search by courseID in the Course mod ...

Initializing start scripts in the package.json file

When launching my react app locally, I need to execute three commands: cd react-web npm run postinstall export REACT_APP_CUSTOMER_ENVIRONMENT=xxx npm start After running these commands, the application server starts on localhost:3000. For the start script ...

What is the best way to incorporate interface validation in TypeScript switch statements?

Currently utilizing Typescript and redux My goal is to compare a passed action with an interface, then execute the appropriate task export function counterReducer( state = initialState, action: CounterActionTypes ): CounterState { switch (action) { ...

Creating a dynamic visual experience with Angular 2: How to implement multiple font colors

I have a text area which is connected to one string, with the default text color set to white. <textarea style="background-color: black;color:#fff;" [(ngModel)]="outputText"></textarea> The connected string contains multiple variables. retur ...

Changing the color of a specific span using Angular

I am working with a dynamic mat-table where columns are added and populated on the fly. The table headers are styled using divs and spans. My goal is to change the color of a header to black when clicked, but also un-toggle any previously selected header. ...

Utilizing REST-API with Angular 2 and Electron

I am encountering an issue with my Electron App that utilizes Angular 2. I had to make a modification from <base href="/"> to <base href="./">, which is a relative path within the file system, in order to make it function properly. However, thi ...

Selecting columns that do not exist in the Sequelize query may result in

Despite my simple creation process, Sequelize insists on selecting a column 'userId' that neither exists nor is being used. After performing some database checks and confirming everything is in order, Sequelize should proceed with the creation p ...

Issue with API showing return value as a single value instead of an array

My database consists of collections for Teachers and Classes. In order to fully understand my issue, it's important to grasp the structure of my database: const TeacherSchema = new Schema( { name: { type: String, required: true } ...

Resetting the timer of an observable in Angular 2

I have a unique service that automatically calls a method every 30 seconds. There is also a button that allows the user to reset the timer, preventing the method from being called for another 30 seconds. How can I make sure that the method does not get cal ...

Is there a way to correct Typescript's misunderstanding of the interface from a JSON file that has been imported?

The structure of my JSON file is as follows: [ { "keys": [ { "date": "2019-06-25T17:33:39.000Z" } ], "tag": null }, { "keys": [], "tag": "stringvalue" } ] Upon importing the file, Typescript assumes that ke ...

In what way can a Express Node app be successfully deployed with npm modules on AWS Lambda?

I am looking to host my node application on AWS Lambda, but I am facing an issue with npm packages that are not pre-installed in lambda. How can I successfully deploy my entire node app on lambda? One option is to upload the files as a zip file, but how ...