node.jsexpressmulter

Why I recieve an typescript error when using req.files.length?


I use multer and want to access req.files but I got this typescript error:

Operator '<' cannot be applied to types 'number' and 'number | File[]'

this error happens when using req.files.lenght;

app.post('/api/upload/images', [upload.array('image')], async (req: Request, res: Response) => {
  try {
    if(!req.files) {
      throw new ErrorException(500, 'Es ist ein Fehler beim Hochladen eines oder mehreren Bildern aufgetreten. Versuchen Sie es erneut.');
    }

    for(let i = 0; i < req.files.length; i++) {
      // Base 64 encode the file to create a data URI for the uploader
      const base64EncodedImage = Buffer.from(req.files[i].buffer).toString("base64")
      const dataUri = `data:${req.files[i].mimetype};base64,${base64EncodedImage}`
      
      // Use the cloudinary uploader to upload the image
      const response = await cloudinary.uploader.upload(dataUri, { folder: '/test2' });
      console.log(response);
    }
  return res.status(201).json({});
  } catch(e) {
    return res.status(500).json({err:'err'});
  }
});

How can I fix the error ? I also get error only at req.files.

Element implicitly has an 'any' type because expression of type 'number' can't be used to index type '{ [fieldname: string]: File[]; } | File[]'.
  No index signature with a parameter of type 'number' was found on type '{ [fieldname: string]: File[]; } | File[]'

Solution

  • Why I receive an typescript error when using req.files.length?

    Because the type of files is, as you show, { [fieldname: string]: File[]; } | File[].

    It's possible that you'd be uploading via multipart/form-data, with e.g.

    <input type="file" name="image">
    <input type="file" name="image">
    <input type="file" name="image">
    

    in which case the shape of req.files would be

    {"image": [File, File, File]}
    

    Since your code always expects an array, move req.files to a local and add a type guard (Array.isArray()) and the rest will typecheck:

    const files = req.files;
    if (!(files && Array.isArray(files))) {
      throw new ErrorException(
        500,
        "Es ist ein Fehler beim Hochladen eines oder mehreren Bildern aufgetreten. Versuchen Sie es erneut.",
      );
    }
    
    for (let i = 0; i < files.length; i++) {
      // Base 64 encode the file to create a data URI for the uploader
      const base64EncodedImage = Buffer.from(files[i].buffer).toString("base64");
      const dataUri = `data:${files[i].mimetype};base64,${base64EncodedImage}`;
    
      // Use the cloudinary uploader to upload the image
      const response = await cloudinary.uploader.upload(dataUri, { folder: "/test2" });
      console.log(response);
    }