node-formidable / formidable

The most used, flexible, fast and streaming parser for multipart form data. Supports uploading to serverless environments, AWS S3, Azure, GCP or the filesystem. Used in production.
MIT License
7.05k stars 682 forks source link

Update index.d.ts #758

Closed ricardo-cavalheiro closed 3 years ago

ricardo-cavalheiro commented 3 years ago

Support plan

Context

What are you trying to achieve or the steps to reproduce?

I was trying to access the path property from the files parameter, but I got the commented error below:

import express from "express";
import formidable from "formidable";
import path from "path";

const app = express();

app.get("/", (req, res) => {
  return res.send("working");
});

app.post("/photo", (req, res) => {
  const form = formidable({
    keepExtensions: true,
    uploadDir: path.resolve("./storage/img"),
  });

  form.parse(req, (error, formName, files) => {
    if (error) {
      console.error("There was an error while parsing the file: " + error);

      return res.status(500).send("did'nt work");
    }

    // Property 'path' does not exist on type 'File | File[]'.
    // Property 'path' does not exist on type 'File[]'.ts(2339)
                                             vv
    return res.status(201).send(files.image.path);
  });
});

app.listen(5678);

What was the result you got?

At runtime, I get the path value, but TS complains about path not being defined when I'm coding.

What result did you expect?

I expect TS to understand that sometimes I get only one file, not an array of files.

The workaround I found is: you need to install the types for formidable with @types/formidable, go to index.d.ts and, at line 180, change:

interface Files {
  [file: string]: File | Files[];
}

to:

interface Files {
  [file: string]: File;
}

I decided to remove the Files[] because I noticed that when form parses a request with more than one image, it does not put the images inside an array but inside a literal object. Therefore, you can access any of these images by using the input's name property in the form tag.

I create a repo to show this issue here.

GrosSacASac commented 3 years ago

In version 3.x it is always an array