Властивість 'value' не існує для типу 'EventTarget'


112

Я використовую TypeScript версії 2 для коду компонента Angular 2.

Я отримую помилку "Властивості" значення "не існує для типу" EventTarget "" для коду нижче, що може бути рішенням. Дякую!

e.target.value.match (/ \ S + / g) || []). довжина

import { Component, EventEmitter, Output } from '@angular/core';

@Component({
selector: 'text-editor',
template: `
<textarea (keyup)="emitWordCount($event)"></textarea>
 `
 })
  export class TextEditorComponent {
   @Output() countUpdate = new EventEmitter<number>();

emitWordCount(e: Event) {
    this.countUpdate.emit(
        (e.target.value.match(/\S+/g) || []).length);
}
}

Відповіді:


186

Вам потрібно чітко вказати TypeScript типу HTMLElement, який є вашою ціллю.

Спосіб це зробити, використовуючи загальний тип, щоб передати його правильному типу:

this.countUpdate.emit((<HTMLTextAreaElement>e.target).value./*...*/)

або (як вам подобається)

this.countUpdate.emit((e.target as HTMLTextAreaElement).value./*...*/)

або (знову ж таки, питання переваги)

const target = e.target as HTMLTextAreaElement;

this.countUpdate.emit(target.value./*...*/)

Це дозволить TypeScript знати, що елемент є a, textareaі він дізнається про значення властивості.

Те ж саме можна зробити з будь-яким елементом HTML, коли ви даєте TypeScript трохи більше інформації про їхні типи, вона окупає вас правильними підказками і, звичайно, меншими помилками.

Щоб полегшити майбутнє, ви можете безпосередньо визначити подію з типом її цілі:

// create a new type HTMLElementEvent that has a target of type you pass
// type T must be a HTMLElement (e.g. HTMLTextAreaElement extends HTMLElement)
type HTMLElementEvent<T extends HTMLElement> = Event & {
  target: T; 
  // probably you might want to add the currentTarget as well
  // currentTarget: T;
}

// use it instead of Event
let e: HTMLElementEvent<HTMLTextAreaElement>;

console.log(e.target.value);

// or in the context of the given example
emitWordCount(e: HTMLElementEvent<HTMLTextAreaElement>) {
  this.countUpdate.emit(e.target.value);
}

@smnbbrv мій випадок - розташування файлів img, потім відобразить img, базуючись на шаблоні SO : <img [src]="url"> <br/> <input type='file' (change)="showImg($event)">Компонент: ... this.url = event.target.result;Іноді це працює іноді, коли це не помиляється. error TS2339: Property 'result' does not exist on type 'EventTarget'Як ви запропонували, скажіть про це більше TS, замість того, що HTMLTextAreaElementя спробував HTMLInputElementтоді target.valueне більше помилка, але зображення не відображається
Jeb50

Я був здивований, побачивши, що ти не можеш передати тип у Eventтип. Ви дійсно повинні мати можливість використовувати Event<HTMLInputElement>як тип.
Ронан

@RoRo подія має такі властивості , аналогічні властивості: target, currentTargetі srcElement; потрібно було б набрати 3 родові типи; навіть якщо вони використовують типи за замовчуванням, наприклад, Event<T = any, C = any, S = any>для згаданих вище, це може бути незручніше, ніж просте asтвердження. Я також міг уявити собі потенційну священну війну для того, що має бути спочатку загальним: targetабо currentTarget. Крім того, багато бібліотек зловживають подіями HTML і потенційно можуть помістити все, що завгодно, у вказані властивості. Ймовірно, це причини, чому вони не зробили це як вбудовані дженерики
smnbbrv

Я використовую панель пошуку в іонах(ionChangeEvent.target as HTMLIonInputElement).value as string
Cloud Cloud

40

Ось простий підхід, який я використав:

const element = event.currentTarget as HTMLInputElement
const value = element.value

Помилка, показана компілятором TypeScript, відсутня, і код працює.


5
fromEvent<KeyboardEvent>(document.querySelector('#searcha') as HTMLInputElement , 'keyup')
    .pipe(
      debounceTime(500),
      distinctUntilChanged(),
      map(e  => {
            return e.target['value']; // <-- target does not exist on {}
        })
    ).subscribe(k => console.log(k));

Можливо, щось подібне може допомогти. Змініть його на основі реального коду. Проблема - це ........ target ['value']


2

Я вважаю, що це має працювати, але я не можу визначити будь-які способи. Інший підхід може бути,

<textarea (keyup)="emitWordCount(myModel)" [(ngModel)]="myModel"></textarea>


export class TextEditorComponent {
   @Output() countUpdate = new EventEmitter<number>();

   emitWordCount(model) {
       this.countUpdate.emit(
         (model.match(/\S+/g) || []).length);
       }
}

2

Ось ще один простий підхід, який я використовував;

    inputChange(event: KeyboardEvent) {      
    const target = event.target as HTMLTextAreaElement;
    var activeInput = target.id;
    }

2

Оскільки я дійшов до двох питань пошуку своєї проблеми дещо по-іншому, я повторюю свою відповідь у випадку, якщо ви опинитесь тут.

У виклику функції ви можете визначити свій тип за допомогою:

emitWordCount(event: { target: HTMLInputElement }) {
  this.countUpdate.emit(event.target.value);
}

Це передбачає, що вас цікавить лише targetмайно, що є найпоширенішим випадком. Якщо вам потрібно отримати доступ до інших властивостей event, більш комплексне рішення передбачає використання &оператора перетину типів:

event: Event & { target: HTMLInputElement }

Ви також можете перейти більш конкретно і замість того, HTMLInputElementщоб використовувати, наприклад, HTMLTextAreaElementдля textareas.


1

Ось ще один спосіб вказати event.target:

import { Component, EventEmitter, Output } from '@angular/core';

@Component({
    selector: 'text-editor',
    template: `<textarea (keyup)="emitWordCount($event)"></textarea>`
})
export class TextEditorComponent {

   @Output() countUpdate = new EventEmitter<number>();

    emitWordCount({ target = {} as HTMLTextAreaElement }) { // <- right there

        this.countUpdate.emit(
          // using it directly without `event`
            (target.value.match(/\S+/g) || []).length);
    }
}

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.