New Typescript 1.8.4 build error: " Build: Property 'result' does not exist on type 'EventTarget'. "

Typescripttypescript1.8

Typescript Problem Overview


I am New to typescript. In my Durandal application I migrated to VS-2012 to VS-2015 means typescript 0.9 to typescript 1.8.4. After migrated I got so many build errors. I resolved all those except one. I am getting below build error on types of Events.

ERROR: " Build: Property 'result' does not exist on type 'EventTarget' "

And the code was exactly like this below:

var reader:any,
target:EventTarget;

reader= new FileReader();
reader.onload = function (imgsrc){
	var fileUrl = imgsrc.target.result;
}

"Imgsrc" is taking type event.

It's working fine with typescript 0.9 but with 1.8.4 it's throwing error as 'result' does not exist on type 'EventTarget'. Can any one help on this to resolve.

Note: "target:EventTarget" is getting from lib.d.ts

Typescript Solutions


Solution 1 - Typescript

Instead of using event.target.result, you can just use FileReader.result.

For example,

const fileReader: FileReader = new FileReader();

fileReader.onload = (event: Event) => {
   event.target.result; // This is invalid
   fileReader.result; // This is valid
};

Solution 2 - Typescript

While any is a medicine (almost for anything, but... where is the TypeScript benefit then)... there is a similar issue reported and nice (TypesScript-ish) workaround suggested

Request to change currentTarget in Event interface for lib.d.ts

let me cite:

> I ran into this TS2339: Property 'result' does not exist on type > 'EventTarget' in JS FileReader onload, and another warning for > getSummary() on the event passed to FileReader's onerror. > > My work-around, to suppress the horrid red squiggily lines;-) is the > following: > > interface FileReaderEventTarget extends EventTarget { > result:string > } >
> interface FileReaderEvent extends Event { > target: FileReaderEventTarget; > getMessage():string; > } > > Then in my app: > > reader.onload = function(fre:FileReaderEvent) { > var data = JSON.parse(fre.target.result); > ... > } >

And, until some change in lib.d.ts, we still do work with known interface

EDIT Dec 2019:

With this fix, you might be getting

> error TS2322: Type '(this: FileReader, e: FileReaderEvent) => void' is not assignable to type '(this: FileReader, ev: ProgressEvent) => any'.

If so, just replace

 interface FileReaderEvent extends Event {

with

 interface FileReaderEvent extends ProgressEvent {

Solution 3 - Typescript

With my old type script the parameter "imgsrc" is having any type by default.

So, now I made it as (imgsrc:any). It's working fine.

var reader:any,
target:EventTarget;
reader= new FileReader();
reader.onload = function (imgsrc:any){
var fileUrl = imgsrc.target.result;
}

Solution 4 - Typescript

The issue is with the typescript definitions. A simple cheat is:

let target: any = e.target; //<-- This (any) will tell compiler to shut up!
let content: string = target.result;

Solution 5 - Typescript

Just let TypScript know what type you would expect it to be.

Here is the fix:

let reader = new FileReader();
reader.onload = function (event){
    let fileUrl = (<FileReader>event.target).result;
}

You could also use reader.result instead in this case

Solution 6 - Typescript

If anyone is finding the simplest solution then this worked for me.

var reader:any,
target:EventTarget;
reader= new FileReader();
reader.onload = function (imgsrc){
//var fileUrl = imgsrc.target.result; //change to
var fileUrl = (imgsrc.target as FileReader).result; //cast to correct type
}

Solution 7 - Typescript

Today this worked for me at TypeScript 2.1.1

interface EventTarget { result: any; }

Solution 8 - Typescript

If this error comes
Type 'string | ArrayBuffer' is not assignable to type 'string'. Type 'ArrayBuffer' is not assignable to type 'string' > fileReader.result+' ';//valid
> fileReader.result; //invalid

Solution 9 - Typescript

I had the same issue in angular with a FileReader.

The solution is rather simple (Typescript has the necessary type). You have to use ProgressEvent<FileReader>. It can be found im lib.dom.d.ts in the typescript installation, so it should be globally availabe if you build with

lib: {
"dom"
}

in your tsconfig.json.

Here is the code where i had to use it:

function read(file: File) {
  const fileReader = new FileReader();
  fileReader.onloadend = function (e: ProgressEvent<FileReader>) {
    const arr = (new Uint8Array(parseInt(e.target.result.toString(), 10))).subarray(0, 4);
    var header = "";
    for (var i = 0; i < arr.length; i++) {
      header += arr[i].toString(16);
    }
    console.log(header);

    // Check the file signature against known types

  };
  fileReader.readAsArrayBuffer(file);
}

Solution 10 - Typescript

instead of

    this.localDbRequest.onsuccess = function (event) {
      const db = event.target.result;
    };

do

   this.localDbRequest.onsuccess = function (event) {
     const db = this.result;
   };

Solution 11 - Typescript

The target object can be accessed as below to prevent error until fix:

reader= new FileReader();
reader.onload = function (imgsrc){
    var fileUrl = imgsrc.target["result"];
}

Treating the target as a Javascript Object

Solution 12 - Typescript

The above solutions didn't fit my similar issue with IndexedDB so I thought I'd share what did work in my scenario. By changing the (event) functions' arguments to (event: any) I was able to ignore the type errors.

Sample Code:

let request = window.indexedDB.open('userChannels', 3);

request.onerror = function(event: any ) {
    console.log('ERROR: Failed to create userChannels local DB' + event.target.errorCode)
  };

request.onsuccess = function(event: any) {
   let db = event.target.result;
   console.log('SUCCESS: Created userChannels local DB')
};

Solution 13 - Typescript

this is a break change of javascript/typescript.

what you will need to do is to just replace "event.target.result" by "this.result".

"this" here refers to the context of interface "MSBaseReader".

below are my implementation excerpt:

      let reader = new FileReader();
      let profile: TransProfile = new TransProfile();

      reader.onload = function(event){
        profile.avatar = new Uint8Array(this.result);
      }

      reader.onerror = function(event){
      }

      this.photoLib.getPhoto(item)
        .then(blob => reader.readAsArrayBuffer(blob))
        .then(() => this.doUpload(profile));

"MSBaseReader" interface definition:

interface MSBaseReader {
    onabort: (this: MSBaseReader, ev: Event) => any;
    onerror: (this: MSBaseReader, ev: ErrorEvent) => any;
    onload: (this: MSBaseReader, ev: Event) => any;
    onloadend: (this: MSBaseReader, ev: ProgressEvent) => any;
    onloadstart: (this: MSBaseReader, ev: Event) => any;
    onprogress: (this: MSBaseReader, ev: ProgressEvent) => any;
    readonly readyState: number;
    readonly result: any;
    abort(): void;
    readonly DONE: number;
    readonly EMPTY: number;
    readonly LOADING: number;
    addEventListener<K extends keyof MSBaseReaderEventMap>(type: K, listener: (this: MSBaseReader, ev: MSBaseReaderEventMap[K]) => any, useCapture?: boolean): void;
    addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}

"FileReader" interface definition

interface FileReader extends EventTarget, MSBaseReader {
    readonly error: DOMError;
    readAsArrayBuffer(blob: Blob): void;
    readAsBinaryString(blob: Blob): void;
    readAsDataURL(blob: Blob): void;
    readAsText(blob: Blob, encoding?: string): void;
    addEventListener<K extends keyof MSBaseReaderEventMap>(type: K, listener: (this: FileReader, ev: MSBaseReaderEventMap[K]) => any, useCapture?: boolean): void;
    addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
}

also note that, due to the context change of "this" within "onload()", your class-based definitions are not accessible within "reader.onload = function(event){..."; meaning you can not use "this.class-property" style to address your class properties.

you will have to define local variable. see the definition and usage of "profile" in above excerpt.

Solution 14 - Typescript

Try this.

event.target["result"]

Solution 15 - Typescript

After lib.dom.d.ts analyzation it is simple:

const fileReader: FileReader = new FileReader();

fileReader.onload = (event: ProgressEvent<FileReader>) => {
   event.target.result; // This is valid
};

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRayuduView Question on Stackoverflow
Solution 1 - TypescriptKimchiManView Answer on Stackoverflow
Solution 2 - TypescriptRadim KöhlerView Answer on Stackoverflow
Solution 3 - TypescriptRayuduView Answer on Stackoverflow
Solution 4 - TypescripttikaView Answer on Stackoverflow
Solution 5 - TypescriptdehartView Answer on Stackoverflow
Solution 6 - TypescriptMelroy FernandesView Answer on Stackoverflow
Solution 7 - TypescriptElcio Mauro GuimarãesView Answer on Stackoverflow
Solution 8 - TypescriptMaravarman ManoharanView Answer on Stackoverflow
Solution 9 - TypescriptLukas KurzView Answer on Stackoverflow
Solution 10 - TypescriptDawitView Answer on Stackoverflow
Solution 11 - TypescriptKeegan CruickshankView Answer on Stackoverflow
Solution 12 - TypescriptKatrpilarView Answer on Stackoverflow
Solution 13 - TypescriptGeorge WangView Answer on Stackoverflow
Solution 14 - TypescriptYouBeeView Answer on Stackoverflow
Solution 15 - TypescriptMichal.SView Answer on Stackoverflow