简体   繁体   中英

ReactJS/TypeScript - Property 'files' does not exist on type 'HTMLElement' error

I am doing a react app with ts and I have this piece of code that returns an error:

  const blobfile = document.getElementById('blobFile');
  if ( blobfile !== null ) {
     const file = blobfile.files[0];
  }

The error is:

Property 'files' does not exist on type 'HTMLElement'

I tried this but does not work:

const file = (<HTMLInputElement>document.getElementById('blobFile')).files[0];

The error for this is:

JSX element type 'HTMLInputElement' is not a constructor function for JSX elements.
  Type 'HTMLInputElement' is missing the following properties from type 'ElementClass': render, context, setState, forceUpdate, and 3 more.ts(2605)
JSX element 'HTMLInputElement' has no corresponding closing tag.ts(17008)

How can I fix this?

Thanks

This is a multi parts answer

Part 1.

If you are using React you should have no reason to use getElementById . You should be using the onChange event of the file input

const onFileChange = (e: ChangeEvent<HTMLInputElement>): void => {
    console.log(e.target.files)
}

<input type="file" onChange={onFileChange} />

Part 2

Your type casting is wrong. The idea to type cast is OK, but not strictly correct and getElementById could return null.

const fileElement = document.getElementById('blobFile') as HTMLInputElement
if (fileElement) {
    console.log(fileElement.files)
}

Thank you very much to you, Leon and Michael!

I am using the Leon solution and my code now is:

   onFileChange = (e: React.ChangeEvent<HTMLInputElement>): any => {
      if ( e.target.files == null ) {
         throw new Error("Error finding e.target.files"); 
      }

      return e.target.files[0];
   }

and the button:

<input type="file" onChange={this.onFileChange} />

For better context (I suppose I had to write it in the original post) I am trying to make functional this guide: https://learn.microsoft.com/en-us/archive/blogs/waws/azure-storage-blob-upload-from-browser

Your cast doesn't work because you're working with tsx, and therefore the cast is ambiguous (typescript can't tell if you're making a cast, or trying to instantiate a component). Instead you should do casts using the as TypeToCastTo

Eg:

 (document.getElementById('blobFile') as HTMLInputElement).files[0];

There is a tslint rule "no-angle-bracket-type-assertion" that might help with this: https://palantir.github.io/tslint/rules/no-angle-bracket-type-assertion/

In addition, you should take a look at Leon's advice regarding using the change event as this is a better solution than querying the document directly - it is very seldom that you would want to do this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM