属性“ files”在类型为“ EventTarget”错误时不存在

我试图访问输入文件的价值从我的 ionic 2应用程序,但我仍然面临的问题,属性文件不存在的类型’事件目标’。 因为它在 js 中正常工作,但是在打字机中不正常工作。 守则如下:

  document.getElementById("customimage").onchange= function(e?) {
var files: any = e.target.files[0];
EXIF.getData(e.target.files[0], function() {
alert(EXIF.getTag(this,"GPSLatitude"));
});
}

请帮助我解决这个问题,因为它不是构建我的离子2应用程序。

102946 次浏览

The e.target property type depends on the element you are returning on getElementById(...). files is a property of input element: https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement

In this case, the TypeScript compiler doesn't know you are returning an input element and we dont have an Event class specific for this. So, you can create one like the following code:

interface HTMLInputEvent extends Event {
target: HTMLInputElement & EventTarget;
}


document.getElementById("customimage").onchange = function(e?: HTMLInputEvent) {
let files: any = e.target.files[0];
//...
}

You can cast it as a HTMLInputElement:

document.getElementById("customimage").onchange = function(e: Event) {
let file = (<HTMLInputElement>e.target).files[0];
// rest of your code...
}

Update:

You can also use this:

let file = (e.target as HTMLInputElement).files[0];

This is more lines, but I think it's the clearest.

    const onChange = (event: Event) => {
const target= event.target as HTMLInputElement;
const file: File = (target.files as FileList)[0];
/** do something with the file **/
};

2022 update: Some people have rightly pointed out that the two casts on the second line are unnecessary, this is totally correct and I've revised my answer.

    const onChange = (event: React.ChangeEvent) => {
const target= event.target as HTMLInputElement;
const file = target.files[0];
/** do something with the file **/
};

I have found that:

<input type="file"  accept="image/*"
(change)="upload($event)">

and

<ion-input type="file"  accept="image/*"
(change)="upload($event)"><ion-input>  or (ionChange)

does not handle the event in the same way. Therefore event.target consists of different parameters.

I therefore did not use the ion-input tag, but the normal angular <input> tag with the (change)="upload($event)" trigger.

It worked for me on Ionic 4.

// use - ChangeEvent<HTMLInputElement>


document.getElementById("customimage").onchange= function(e?: ChangeEvent<HTMLInputElement>) {
var files: any = e.target.files[0];
EXIF.getData(e.target.files[0], function() {
alert(EXIF.getTag(this,"GPSLatitude"));
});
}
const handleFileInput = (event: ChangeEvent) => {
const target = event.target as HTMLInputElement;
const file: File = (target.files as FileList)[0];
/** do something with the file **/
};

I would change Event to ChangeEvent, however the rest of Devin Clark's answer is great :)

const onChange => (event: Event): void {
const input = event.target as HTMLInputElement;


if (!input.files?.length) {
return;
}


const file = input.files[0];
console.log(file);
}

Better avoid Type Casting whenever possible. Use e.currentTarget instead of e.target

I just come to solved the same probleme, when I use :

e.target.files

It said that target doesnot have files property, so as you said in type script. You can also use :

e.target['files'][0]

It solved my probleme.

Based on a few other answers and slight refactoring over time I now commonly cast the ChangeEvent in one line like so:

const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const files = e.target.files;
if (!files || !files.length) {
alert("Please select a file!");
}
}