Jerry
Jerry

Reputation: 1583

Typescript Error: Property 'files' does not exist on type 'HTMLElement'

I wish to create an upload function for my Apps by using IONIC.

Here is my HTML code:

<input ion-button block type="file" id="uploadBR">
<input ion-button block type="file" id="uploadIC">
<button ion-button block (click)="upload()">Confirm Claim Restaurant</button>

Here is my upload() function:

upload(){   
   let BR = document.getElementById('uploadBR').files[0]
   let IC = document.getElementById('uploadIC').files[0]
   console.log(BR)
   console.log(IC)    
 }

In normal HTML it should work, but it doesn't work with my IONIC.

When building the App, it will show the error Typescript Error: Property 'files' does not exist on type 'HTMLElement'.

Am i do it in wrong way or it has to be done in different way with typescript?

Thanks.

Upvotes: 27

Views: 25122

Answers (3)

esamatti
esamatti

Reputation: 18944

Instead of casting you might want to consider checking that you actually have the correct type:

const br = document.getElementById('uploadBR');


if (!(br instanceof HTMLInputElement)) {
    throw new Error("Expected an HTMLInputElement");
}

because if you make a typo in the 'uploadBR' string or change the underlying html you'll get an unhelpful runtime exception because the return value will not be HTMLInputElement and TypeScript will be perfectly happy with it because of the casting.

To make it even cleaner you can make an assertion function for it

function assertHTMLInput(el: any): asserts el is HTMLInputElement {
    if (!(el instanceof HTMLInputElement)) {
        throw new Error("Expected to be an input");
    }
}

Usage

let BR = document.getElementById("uploadBR");
let IC = document.getElementById("uploadIC");
assertHTMLInput(BR);
assertHTMLInput(IC);

// ✅ Properly typed
console.log(BR.files[0]);
console.log(IC.files[0]);

Upvotes: 1

ranjeet8082
ranjeet8082

Reputation: 2359

You need to cast it as a HTMLInputElement as files is a property of input element

let BR = (<HTMLInputElement>document.getElementById('uploadBR')).files[0];

Upvotes: 66

Venkataramanan
Venkataramanan

Reputation: 73

In a React.js project you might want to use 'as' to cast because the <> syntax does not work in .tsx files

const file = (document.getElementById(id) as HTMLInputElement).files[0];

Upvotes: 6

Related Questions