Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Defining type for input file state: React+Typescript

I am getting the following error while I define the type of file object inside state, Argument of type 'null' is not assignable to parameter of type 'File | (() => File)'.ts. I am having a upload component, that basically takes care of selecting the file and sending its value to the parent component. I am trying to this in a typescript way and I am unable to get rid of this.

Link to the sandbox: https://codesandbox.io/s/react-hook-upload-oxqdp2?file=/src/Upload.tsx

Upload

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

import * as React from "react";
import { Button } from "@material-ui/core";
import { useState } from "react";

interface UploaderProps {
  fileType?: string | AcceptedFileType[];
}

enum AcceptedFileType {
  Text = ".txt",
  Gif = ".gif",
  Jpeg = ".jpg",
  Png = ".png",
  Doc = ".doc",
  AllImages = "image/*",
  AllVideos = "video/*",
  AllAudios = "audio/*"
}

export const Upload = (props: UploaderProps): JSX.Element => {
  const { fileType } = props;
  const acceptedFormats: string | AcceptedFileType[] =
    typeof fileType === "string"
      ? fileType
      : Array.isArray(fileType)
      ? fileType?.join(",")
      : AcceptedFileType.Text;
  const [selectedFiles, setSelectedFiles] = useState<File>(null);

  const handleFileSelect = (event: React.ChangeEvent<HTMLInputElement>) => {
    setSelectedFiles(event?.target?.files?.[0]);
  };

  const onUpload = () => {
    // eslint-disable-next-line no-console
    console.log(selectedFiles);
  };

  return (
    <>
      <Button
        variant="contained"
        component="label"
        style={{ textTransform: "none" }}
      >
        <input
          hidden
          type="file"
          accept={acceptedFormats}
          onChange={handleFileSelect}
        />
        <span> Choose file to upload</span>
      </Button>
      <Button
        color="primary"
        disabled={!selectedFiles}
        style={{ textTransform: "none" }}
        onClick={onUpload}
      >
        Upload
      </Button>
    </>
  );
};

Can someone help?

>Solution :

You should probably stick to undefined:

const [selectedFiles, setSelectedFiles] = useState<File | undefined>(undefined);

const handleFileSelect = (event: React.ChangeEvent<HTMLInputElement>) => {
  setSelectedFiles(event?.target?.files?.[0]);
};

This is because when you set it, the value has the type File | undefined.

This will also force you to check the value before using it, since it could be undefined.

If you know that there will be a file, you can use an assertion with !:

setSelectedFiles(event?.target?.files?.[0]!);

and maybe keep the type as File | null, but even then I’d still use File | undefined because null is a bit quirky in JavaScript (typeof null === "object').

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading