Właściwość „wartość” nie istnieje w typie „EventTarget”


115

Używam TypeScript w wersji 2 dla kodu składnika Angular 2.

Otrzymuję błąd „Wartość właściwości” nie istnieje dla typu „EventTarget” dla poniższego kodu, jakie może być rozwiązanie. Dzięki!

e.target.value.match (/ \ S + / g) || []).długość

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

Odpowiedzi:


189

Musisz jawnie podać TypeScript typ elementu HTMLElement, który jest Twoim celem.

Aby to zrobić, użyj typu ogólnego, aby rzutować go na właściwy typ:

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

lub (jak chcesz)

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

lub (znowu, kwestia preferencji)

const target = e.target as HTMLTextAreaElement;

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

Dzięki temu TypeScript będzie wiedział, że element jest plikiem textarea i będzie wiedział o właściwości value.

To samo można zrobić z każdym rodzajem elementu HTML, ilekroć podasz TypeScript nieco więcej informacji o ich typach, odwdzięczy się to odpowiednimi wskazówkami i oczywiście mniejszą liczbą błędów.

Aby ułatwić sobie na przyszłość, możesz chcieć bezpośrednio zdefiniować zdarzenie z typem jego celu:

// 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 mój przypadek to lokalizacja pliku img, a następnie wyświetl img, w oparciu o Szablon SO : <img [src]="url"> <br/> <input type='file' (change)="showImg($event)">Składnik: ... this.url = event.target.result;Czasami działa czasami nie, jeśli nie jest to błąd error TS2339: Property 'result' does not exist on type 'EventTarget'Tak jak zasugerowałeś, powiedz TS więcej o tym, w miejscu, HTMLTextAreaElementktóre próbowałem, HTMLInputElementa potem target.valuenie więcej err, ale obraz się nie wyświetla.
— Jeb50

Zaskoczyło mnie, że nie można przekazać typu do Eventczcionki. Naprawdę powinieneś być w stanie użyć Event<HTMLInputElement>jako typu.
— Ronan

Zdarzenie @RoRo ma następujące właściwości podobne: target, currentTargeti srcElement; należałoby wpisać 3 typy ogólne; nawet jeśli używają domyślnych typów, np. Event<T = any, C = any, S = any>dla wyżej wymienionych, może być bardziej niewygodne w użyciu niż proste asstwierdzenie. Mogę również wyobrazić sobie potencjalny holywar dla tego, co powinno być najpierw ogólne: targetlub currentTarget. Ponadto wiele bibliotek nadużywa zdarzenia HTML i może potencjalnie umieścić wszystko, czego chcą, we wspomnianych właściwościach. Prawdopodobnie są to powody, dla których nie zrobili tego jako wbudowane
— typy

Na moim pasku wyszukiwania jonów używam(ionChangeEvent.target as HTMLIonInputElement).value as string
— Cloud

40

Oto proste podejście, którego użyłem:

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

Błąd wyświetlany przez kompilator TypeScript zniknął i kod działa.


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

Może coś takiego jak powyższe mogłoby pomóc. Zmień to w oparciu o rzeczywisty kod. Problem jest ........ target ['value']


2

Uważam, że to musi działać, ale nie mogę zidentyfikować żadnych sposobów. Innym podejściem może być:

<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

Oto inne proste podejście, którego użyłem;

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

2

Ponieważ dotarłem do dwóch pytań, szukając mojego problemu w nieco inny sposób, powtarzam swoją odpowiedź na wypadek, gdybyś tu znalazł się.

W wywołanej funkcji możesz zdefiniować swój typ za pomocą:

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

Zakłada się, że interesuje Cię tylko targetnieruchomość, co jest najczęstszym przypadkiem. Jeśli chcesz uzyskać dostęp do innych właściwości programu event, bardziej kompleksowe rozwiązanie obejmuje użycie &operatora przecięcia typu:

event: Event & { target: HTMLInputElement }

Możesz również przejść bardziej szczegółowo i zamiast HTMLInputElementużywać, na przykład, HTMLTextAreaElementdla obszarów tekstowych.


1

Oto jeszcze jeden sposób określenia 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);
    }
}

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.