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

Viewed 52633

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

15 Answers

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

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

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
}

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

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

instead of

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

do

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

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

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

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
};
Related