ChatGPT解决这个技术问题 Extra ChatGPT

打字稿中的类型“EventTarget”错误中不存在属性“文件”

我正在尝试从我的 ionic 2 应用程序访问输入文件的值,但我仍然面临“EventTarget”类型上不存在属性文件的问题。因为它可以在 js 中正常工作,但不能在 typescript 中正常工作。代码如下:

  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"));
              });
          }

请帮我解决这个问题,因为它没有构建我的 ionic 2 应用程序。


F
Francesco Borzi

您可以将其转换为 HTMLInputElement:

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

更新:

你也可以使用这个:

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

这为我解决了。我会接受它作为正确答案。
你是用ts写的吗?
@AliSajid 是的,看看这个:blogs.microsoft.co.il/gilf/2013/01/18/…
事件正在传播,target 可能是不同类型的其他元素。最好使用 e.currentTarget,它是 HTMLInputElement
D
Diullei

e.target 属性类型取决于您在 getElementById(...) 上返回的元素。 filesinput 元素的属性:https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement

在这种情况下,TypeScript 编译器不知道您正在返回 input 元素,并且我们没有专门用于此的 Event 类。因此,您可以创建一个类似以下代码的代码:

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

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

正如下面有人建议的那样,您可以只使用:“e:any”。我想知道使用这里提供的方法的优点是什么?
@Tomer,这更有可能是因为丢失打字稿类型没有好处。每次使用“any”时,都会删除类型保护。
非常正确。简而言之,如果你在这里使用“any”,你还不如根本不使用 TypeScript。这有点夸张——众所周知,当我不想为单个函数的参数定义类型时,我会使用“any”——但逻辑是一致的;使用 TypeScript 的唯一原因是允许编译器通过防止您犯基于类型的错误来帮助您。
我喜欢建议的方法,但我不确定 & EventTarget 部分的目的。我了解目标:HTMLInputElement 向扩展类型事件添加了一个属性,该属性称为目标并且属于 HTMLInputElement 类型。但是我们通过说“哦,对,它也可以是另一种类型......”得到什么。我在这里想念什么?
D
Devin Clark

这是更多的线条,但我认为这是最清晰的。

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

2022 更新:有些人正确地指出,第二行的两次强制转换是不必要的,这是完全正确的,我已经修改了我的答案。

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

当我尝试访问 $event.target 时,您会为 reader.onloadend = ($event: ProgressEvent) => { ... } 建议什么类型?目标是具有名为 result 的属性的类型,但我的 TsLint 抱怨该属性不存在(当然,由于我没有正确设置类型)。
我的意思是像 this samplee.targete.target.result 的类型是什么?
您不需要转换文件。当您转换 HTMLInputElement 时,它会自动推断 target.files 类型。另外,四处施放一切都是危险的。你施放的越少越好。
我浏览了至少一半的互联网来找到这个解决方案。很难向其他开发人员解释为什么在计算中需要强类型。非常感谢@Devin Clark
d
darmou
const handleFileInput = (event: ChangeEvent) => {
        const target = event.target as HTMLInputElement;
        const file: File = (target.files as FileList)[0];
        /** do something with the file **/
    };

我会将 Event 更改为 ChangeEvent,但是 Devin Clark 的其余部分的回答很棒:)


s
skinnynpale
// 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"));
              });
          }

我认为这个答案应该被接受。至少它对我有用。
n
nkitku
const onChange => (event: Event): void {
    const input = event.target as HTMLInputElement;

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

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

请解释您的回答,stackoverflow.com/help/how-to-answer
ס
סטנלי גרונן

我发现:

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

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

不以相同的方式处理事件。因此 event.target 由不同的参数组成。

因此,我没有使用 ion-input 标记,而是使用带有 (change)="upload($event)" 触发器的普通角度 <input> 标记。

它在 Ionic 4 上对我有用。


a
arudzevych

尽可能避免类型转换。使用 e.currentTarget 代替 e.target


A
Alex Dunlop

基于其他一些答案和随着时间推移的轻微重构,我现在通常将 ChangeEvent 转换为一行,如下所示:

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

I
Ibrahim Kelly

当我使用时,我只是解决了同样的问题:

e.target.files

它说目标没有文件属性,就像你在类型脚本中所说的那样。您还可以使用:

e.target['files'][0]

它解决了我的问题。