Нова помилка збірки Typescript 1.8.4: “Збірка: Властивість 'result' не існує для типу 'EventTarget'. "


75

Я новачок у машинописі. У моїй програмі Durandal я перейшов на VS-2012 до VS-2015 означає машинопис 0.9 від машинопису 1.8.4. Після міграції я отримав стільки помилок збірки. Я вирішив усіх, крім одного. Я отримую нижче помилки збірки для типів подій.

ПОМИЛКА: "Збірка: властивість 'result' не існує у типі 'EventTarget'"

І код був точно таким, як показано нижче:

var reader:any,
target:EventTarget;

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

"Imgsrc" бере подію типу.

Він чудово працює з машинописом 0.9, але з 1.8.4 помилка викиду, оскільки «результат» не існує для типу «EventTarget». Хто-небудь може допомогти з цим вирішити.

Примітка: "target: EventTarget" отримується з lib.d.ts

Відповіді:


74

Хоча anyце ліки (майже для чого завгодно, але ... де тоді перевага TypeScript) ... є подібна інформація про проблему та пропонується приємне (TypesScript-іш) обхідне рішення

Запит на зміну currentTarget в інтерфейсі подій для lib.d.ts

дозвольте мені цитувати:

Я зіткнувся з цим TS2339: Властивість 'result' не існує для типу 'EventTarget' у JS FileReader onload, і ще одне попередження для getSummary () щодо події, переданої FileReader's onerror.

Моє обхідне завдання, щоб придушити жахливі червоні звивисті лінії ;-), полягає в наступному:

interface FileReaderEventTarget extends EventTarget {
    result:string
}

interface FileReaderEvent extends Event {
    target: FileReaderEventTarget;
    getMessage():string;
}

Тоді в моєму додатку:

reader.onload = function(fre:FileReaderEvent) {
    var data = JSON.parse(fre.target.result);
    ...
}

І доки не буде змін у lib.d.ts, ми все ще працюємо з відомим інтерфейсом

EDIT грудень 2019:

За допомогою цього виправлення, можливо, ви отримуєте

помилка TS2322: Тип '(this: FileReader, e: FileReaderEvent) => void' не можна призначити типу '(this: FileReader, ev: ProgressEvent) => any'.

Якщо так, просто замініть

 interface FileReaderEvent extends Event {

з

 interface FileReaderEvent extends ProgressEvent {

5
Все ще не зафіксовано станом на кінець квітня 2018 року
Фергал Моран,

10
На початку червня 2018 р.
Все ще не зафіксовано

6
Все ще не фіксовано. Жовтень 2018 р.
Jeff Huijsmans

10
досі нефіксований. Листопад 4,2018
Тисне

15
Досі не зафіксовано станом на січень 2019 р.
Віктор Фернандес

74

Замість того, щоб використовувати event.target.result, ви можете просто використовувати FileReader.result.

Наприклад,

const fileReader: FileReader = new FileReader();

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

1
не може проаналізувати як json :(
roadev

@KimchiMan .. Чудово ... Чи можете ви пояснити, як.?
Dila Gurung

1
Якщо ця помилка з'являється <br> Введіть 'string | ArrayBuffer 'не можна призначити для введення' рядок '. Тип 'ArrayBuffer' не можна призначити типу 'рядок' <br/>> fileReader.result; + '';
Мараварман Манохаран

2
це повинна бути прийнята відповідь, чиста і без участі хакерів
Богдан Іоніца

1
Насправді це ProgressEvent<FileReader>не просто Event...
небезпека89

36

У моєму старому сценарії типу параметр "imgsrc" має будь-який тип за замовчуванням.

Отже, зараз я зробив це як (imgsrc: any). Це працює нормально.

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

21

Справа в визначеннях машинопису. Простий обман:

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

16

Просто повідомте TypScript, якого типу ви б очікували.

Ось виправлення:

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

Ви також можете використовувати reader.resultзамість цього в цьому випадку


Це найкраще рішення
Адам Шнайдер

6

Якщо хтось знаходить найпростіше рішення, тоді це спрацювало для мене.

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
}

3

Сьогодні це працювало для мене в TypeScript 2.1.1

interface EventTarget { result: any; }

1
Приємне рішення, однак, коли я перезапустив рішення, воно видає багато помилок у lib.d.ts. Він стикається з реальним інтерфейсом EventTarget.
Ревілс

2

Якщо ця помилка з'являється,
введіть 'string | ArrayBuffer 'не можна призначити для введення' рядок '. Тип 'ArrayBuffer' не можна призначити типу 'рядок'

fileReader.result + ''; // дійсний
файлReader.result; // недійсний


2

У мене була та ж проблема в angular з a FileReader .

Рішення досить просте (Typescript має необхідний тип). Ви повинні використовувати ProgressEvent<FileReader>. Її можна знайти lib.dom.d.tsв установці машинопису, тому вона повинна бути доступна у всьому світі, якщо ви будуєте за допомогою

lib: {
"dom"
}

у вашому tsconfig.json.

Ось код, де мені довелося його використовувати:

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


1

замість

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

робити

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

1

До цільового об’єкта можна отримати доступ, як показано нижче, щоб уникнути помилок до виправлення:

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

Обробка цілі як об’єкта Javascript


1

Вищевказані рішення не відповідали моїй подібній проблемі з IndexedDB, тому я подумав поділитися тим, що працювало в моєму сценарії. Змінивши (event)аргументи функцій на(event: any) Я», я зміг проігнорувати помилки типу.

Зразок коду:

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

0

це перерва в зміні JavaScript / TypeScript.

що вам потрібно буде зробити, це просто замінити "event.target.result" на "this.result".

"this" тут стосується контексту інтерфейсу "MSBaseReader".

нижче мій фрагмент моєї реалізації:

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

також зауважте, що через зміну контексту "this" у межах "onload ()", визначення на основі вашого класу недоступні в "reader.onload = function (event) {..."; це означає, що ви не можете використовувати стиль "this.class-property" для звернення до властивостей класу.

вам доведеться визначити локальну змінну. див. визначення та використання "профілю" у наведеному вище уривку.


0

Спробуйте це.

event.target["result"]

Хоча цей код може вирішити проблему OP, найкраще включити пояснення щодо того, як ваш код вирішує проблему OP. Таким чином, майбутні відвідувачі можуть вчитися на вашому дописі та застосовувати його до власного коду. SO - це не служба кодування, а ресурс для знань. Крім того, якісні, повні відповіді, швидше за все, проголосують. Ці особливості, поряд із вимогою, щоб усі дописи були автономними, є сильними сторонами SO як платформи, яка відрізняє його від форумів. Ви можете редагувати, щоб додати додаткову інформацію та / або доповнити свої пояснення вихідною документацією.
ysf
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.