【问题标题】:Property 'files' does not exist on type 'EventTarget' error in typescript打字稿中的“EventTarget”类型错误中不存在属性“文件”
【发布时间】:2017-08-27 20:14:24
【问题描述】:

我正在尝试从我的 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 应用程序。

【问题讨论】:

    标签: angular typescript ionic2 exif-js


    【解决方案1】:

    您可以将其转换为 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
    【解决方案2】:

    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 部分的用途。我了解 target: HTMLInputElement 向扩展类型 Event 添加了一个属性,该属性称为 target 并且是 HTMLInputElement 类型.但是我们通过说“哦,对了,它也可以是另一种类型......”得到什么。我在这里错过了什么?
    【解决方案3】:

    这是更多的台词,但我认为这是最清晰的。

        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.目标?目标是具有名为 result 的属性的类型,但我的 TsLint 抱怨该属性不存在(当然,由于我没有正确设置类型)。
    • 我的意思是像this samplee.targete.target.result 的类型是什么?
    • 您不需要转换文件。当您转换 HTMLInputElement 时,它会自动推断 target.files 类型。另外,四处施放一切都是危险的。你施放的越少越好。
    • 我浏览了至少一半的互联网来找到这个解决方案。很难向其他开发人员解释为什么在计算中需要强类型。非常感谢@Devin Clark
    【解决方案4】:
    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 的其余部分的回答很棒:)

    【讨论】:

      【解决方案5】:
      // 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"));
                    });
                }
      

      【讨论】:

      • 我认为这个答案应该被接受。至少它对我有用。
      【解决方案6】:
      const onChange => (event: Event): void {
          const input = event.target as HTMLInputElement;
      
          if (!input.files?.length) {
              return;
          }
      
          const file = input.files[0];
          console.log(file);
      }
      

      【讨论】:

      【解决方案7】:

      我发现:

      <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)" 触发器的普通角度&lt;input&gt; 标签。

      它在 Ionic 4 上对我有用。

      【讨论】:

        【解决方案8】:

        尽可能避免类型转换。使用e.currentTarget 而不是 e.target

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-02-19
          • 1970-01-01
          • 2020-05-05
          • 2017-03-26
          • 2021-10-23
          • 2019-07-20
          • 1970-01-01
          • 2018-10-19
          相关资源
          最近更新 更多