La propriété 'value' n'existe pas sur le type 'EventTarget'

115

J'utilise TypeScript Version 2 pour un code de composant Angular 2.

J'obtiens l'erreur "La propriété 'valeur' ​​n'existe pas sur le type 'EventTarget'" pour le code ci-dessous, quelle pourrait être la solution. Merci!

e.target.value.match (/ \ S + / g) || []).longueur

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);
}
}
user584018
la source

Réponses:

189

Vous devez indiquer explicitement à TypeScript le type de HTMLElement qui est votre cible.

La façon de le faire consiste à utiliser un type générique pour le convertir en un type approprié:

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

ou (comme vous le souhaitez)

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

ou (encore une fois, question de préférence)

const target = e.target as HTMLTextAreaElement;

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

Cela permettra à TypeScript de savoir que l'élément est a textareaet de connaître la propriété value.

La même chose pourrait être faite avec n'importe quel type d'élément HTML, chaque fois que vous donnez à TypeScript un peu plus d'informations sur leurs types, cela vous paie avec des conseils appropriés et bien sûr moins d'erreurs.

Pour vous faciliter la tâche dans le futur, vous souhaiterez peut-être définir directement un événement avec le type de sa cible:

// 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
la source
@smnbbrv mon cas est un emplacement de fichier img puis affichez l'img, basé sur SO Template: <img [src]="url"> <br/> <input type='file' (change)="showImg($event)">Component: ... this.url = event.target.result;Parfois, ça marche parfois pas, quand ce n'est pas une erreur, error TS2339: Property 'result' does not exist on type 'EventTarget'comme vous l'avez suggéré, dites-en plus à TS, à l'endroit où HTMLTextAreaElementj'ai essayé, HTMLInputElementalors target.valueplus err mais l'image ne s'affiche pas.
Jeb50
J'ai été surpris de voir que vous ne pouviez pas passer un type dans le Eventtype. Vous devriez vraiment pouvoir utiliser Event<HTMLInputElement>comme type.
Ronan
Événement @RoRo a des propriétés similaires suivantes: target, currentTargetet srcElement; il faudrait taper 3 types génériques; même s'ils utilisent des types par défaut, par exemple Event<T = any, C = any, S = any>pour ce qui est mentionné ci-dessus, il pourrait être plus inconfortable à utiliser que l' asinstruction simple . Je pourrais aussi imaginer une guerre sacrée potentielle pour ce qui devrait être d'abord générique: targetou currentTarget. De plus, de nombreuses bibliothèques abusent des événements HTML et peuvent potentiellement mettre tout ce qu'elles veulent dans les propriétés mentionnées. Ce sont probablement les raisons pour lesquelles ils ne l'ont pas fait en tant que génériques
intégrés
Pour ma barre de recherche ionique, j'utilise(ionChangeEvent.target as HTMLIonInputElement).value as string
Cloud le
40

Voici l'approche simple que j'ai utilisée:

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

L'erreur affichée par le compilateur TypeScript a disparu et le code fonctionne.

Torsten Barthel
la source
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));

Peut-être que quelque chose comme ce qui précède pourrait vous aider. Changez-le en fonction du vrai code. Le problème est ........ target ['value']

Ahmed
la source
2

Je pense que cela doit fonctionner, mais je ne suis pas en mesure d'identifier de toute façon. Une autre approche peut être,

<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);
       }
}
micronyques
la source
2

Voici une autre approche simple, que j'ai utilisée;

    inputChange(event: KeyboardEvent) {      
    const target = event.target as HTMLTextAreaElement;
    var activeInput = target.id;
    }
Burak Odabaş
la source
2

Depuis que j'ai atteint deux questions recherchant mon problème d'une manière légèrement différente, je réplique ma réponse au cas où vous vous retrouveriez ici.

Dans la fonction appelée, vous pouvez définir votre type avec:

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

Cela suppose que vous n'êtes intéressé que par la targetpropriété, ce qui est le cas le plus courant. Si vous avez besoin d'accéder aux autres propriétés de event, une solution plus complète consiste à utiliser l' &opérateur d'intersection de type:

event: Event & { target: HTMLInputElement }

Vous pouvez également aller plus spécifique et au lieu d'utiliser, HTMLInputElementvous pouvez utiliser par exemple HTMLTextAreaElementpour les zones de texte.

belvédère
la source
1

Voici une autre façon de spécifier 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);
    }
}

qiAlex
la source