angular - Proprietatea 'value' nu există pe tipul 'EventTarget'


Folosesc TypeScript versiunea 2 pentru codul unui component Angular 2.

Primesc eroarea „Proprietatea 'value' nu există pe tipul 'EventTarget'” pentru codul de mai jos, care ar putea fi soluția? Mulțumesc!

e.target.value.match(/\S+/g) || []).length
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);
  }
}

Răspuns #1

Trebuie să îi spui în mod explicit TypeScript tipul de HTMLElement care este ținta ta.

Modul de a face acest lucru este folosind un tip generic pentru a-l converti la un tip corespunzător:

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

sau (după cum vrei)

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

sau (din nou, o chestiune de preferință)

const target = e.target as HTMLTextAreaElement;

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

Acest lucru va permite TypeScript să știe că elementul este un textarea și va cunoaște proprietatea value.

Același lucru se poate face cu orice tip de element HTML, ori de câte ori îi oferi TypeScript puțin mai multe informații despre tipurile lor, acesta îți răsplătește cu sugestii corecte și, desigur, cu mai puține erori.

Pentru a face lucrurile mai ușoare în viitor, s-ar putea să vrei să definești direct un eveniment cu tipul țintei sale:

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

Răspunsul #2

Iată abordarea simplă pe care am folosit-o:

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

Eroarea afișată de compilatorul TypeScript a dispărut și codul funcționează.

Răspunsul #3

Pentru cei care primesc această eroare în Angular 13, după actualizarea de la o versiune anterioară

Problema pentru mine a fost că foloseam următoarele în HTML-ul meu (ceea ce era permis înainte)

(keyup)="applyFilter($event.target.value)" 

Remedierea pentru aceasta a fost:

HTML :

(keyup)="applyFilter($event)"

Componentă - în funcția mea apelată:

applyFilter(event: Event) {
    const filterValue = (event.target as HTMLInputElement).value;
    // ... etc...
}

Și acum aș putea folosi din nou filterValue ca înainte.

Răspunsul #4

În cazul meu, am avut:

const handleOnChange = (e: ChangeEvent) => {
  doSomething(e.target.value);
}

Și problema a fost că nu am furnizat un argument de tip pentru ChangeEvent, astfel încât să știe că e.target era un HTMLInputElement. Chiar dacă i-am spus manual că target era un element de input (de exemplu const target: HTMLInputElement=e.target), ChangeEvent tot nu înțelegea că asta avea sens.

Soluția era să faci:

// add type argument
const handleOnChange = (e: ChangeEvent<HTMLInputElement>) => {
  doSomething(e.target.value);
}

Răspunsul #5

Deoarece am ajuns la două întrebări căutând problema mea într-un mod ușor diferit, îmi repet răspunsul în caz că ajungeți aici.

În funcția apelată, vă puteți defini tipul cu:

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

Aceasta presupune că sunteți interesat doar de proprietatea target, ceea ce este cel mai frecvent caz. Dacă trebuie să accesați celelalte proprietăți ale event, o soluție mai cuprinzătoare implică utilizarea operatorului de intersecție de tip &:

event: Event & { target: HTMLInputElement }

De asemenea, poți fi mai specific și, în loc să folosești HTMLInputElement, poți folosi, de exemplu, HTMLTextAreaElement pentru zonele de text.

Răspuns #6

Angular 10+

Deschide tsconfig.json și dezactivează strictDomEventTypes.

  "angularCompilerOptions": {
    ....
    ........
    "strictDomEventTypes": false
  }

Răspunsul #7

Nu folosi soluțiile din celelalte răspunsuri care implică transformarea tipului evenimentului, a țintei evenimentului sau dezactivarea completă a verificării tipurilor. Nu este sigur.

În schimb, ar trebui să „extragi” valoarea din elementul HTML și să o transmiți ca argument în schimb.

Exemplu exagerat de simplificat:

<input #searchBox type="text" (input)="doSearch(searchBox.value)">
doSearch(text: string): void {
}

Deci, dacă extinzi asta la exemplul original, ar trebui să obții asta:

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

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

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

Răspunsul #8

consideră $any()

<textarea (keyup)="emitWordCount($any($event))"></textarea>

Răspunsul #9

Iată o altă abordare simplă pe care am folosit-o;

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