191 votes

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

Donc le code suivant est en Angular 4 et je ne comprends pas pourquoi il ne fonctionne pas comme prévu.

Voici un extrait de mon gestionnaire:

onUpdatingServerName(event: Event) {
  console.log(event);
  this.newserverName = event.target.value; //ce ne fonctionnera pas
}

Élément HTML:

Le code me donne l'erreur:

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

Mais comme on peut le voir dans le console.log, la valeur existe sur event.target.

6 votes

Nous pouvons utiliser (e.target en tant que HTMLInputElement).value

0 votes

Bro, j'ai eu du mal avec ça pendant des heures, il suffit simplement de supprimer le type de la méthode. onUpdatingServerName(event);

232voto

Li357 Points 31390

event.target ici est un HTMLElement qui est le parent de tous les éléments HTML, mais dont la propriété value n'est pas garantie. TypeScript détecte cela et génère une erreur. Effectuez une conversion de event.target à l'élément HTML approprié pour vous assurer qu'il s'agit bien d'un HTMLInputElement qui possède une propriété value:

(event.target).value

Conformément à la documentation:

Type the $event

L'exemple ci-dessus convertit le $event en un type any. Cela simplifie le code mais avec un coût. Il n'y a pas d'informations de type qui pourraient révéler les propriétés de l'objet événement et éviter des erreurs stupides.

[...]

Le $event est désormais un KeyboardEvent spécifique. Tous les éléments n'ont pas une propriété valuetarget en un élément input.

(Ma mise en emphase)

50 votes

Une syntaxe un peu plus propre var element = ev.target as HTMLElement

5 votes

Pour moi, HTMLInputElement a fonctionné à la place de HTMLElement car HTMLElement n'a pas de valeur dans l'interface.

3 votes

La meilleure approche, à mon avis, est d'avoir onFieldUpdate(event: { target: HTMLInputElement }) { dans la fonction appelée. Voir ma réponse ci-dessous.

124voto

Mikael Lirbank Points 51

Passer HTMLInputElement en tant que générique au type d'événement devrait également fonctionner :

onUpdatingServerName(event: React.ChangeEvent) {
  console.log(event);
  this.newserverName = event.target.value;
}

16 votes

Ceci est mieux que les assertions de type.

5 votes

Cela ne fonctionnera pas si la fonction est appelée depuis par exemple un gestionnaire de propriété onChange dans le code React. Le gestionnaire React ne s'attend pas à ce que le type soit défini pour React.ChangeEvent et affichera une erreur de typage. J'ai donc dû revenir à (une variante de) la réponse sélectionnée, avec une conversion forcée : (event.target as HTMLInputElement).value.

0 votes

Cela semblait bien fonctionner pour moi dans un composant React. Peut-être est-ce la version de React ? Nous sommes actuellement sur la version 16.8.*.

73voto

Matt S. Points 211

Voici une autre solution qui fonctionne pour moi :

(event.target as HTMLInputElement).value

Cela devrait éliminer l'erreur en permettant à TS de savoir que event.target est un HTMLInputElement, qui a intrinsèquement une valeur. Avant de spécifier, TS savait probablement seulement que event seul était un HTMLInputElement, donc selon TS la cible entrée était une valeur cartographiée au hasard qui pouvait être n'importe quoi.

8 votes

Cela a été vraiment utile en React où il a essayé d'interpréter comme du JSX.

0 votes

Translated in French with HTML tags preserved:

Hey man, thanks for share! This solution fits for me.

27voto

Beau Smith Points 8112

J'étais à la recherche d'une solution à une erreur similaire de TypeScript avec React :

La propriété 'dataset' n'existe pas sur le type EventTarget en TypeScript

Je voulais accéder à event.target.dataset d'un élément de bouton cliqué dans React :

  Supprimer le candidat

Voici comment j'ai pu faire en sorte que la valeur de dataset "existe" via TypeScript :

const onClickHandler = (event: React.MouseEvent) => {
  const { name, index } = (event.target as HTMLButtonElement).dataset
  console.log({ name, index })
  // faire des choses avec name et index…
}

2 votes

La question est étiquetée comme Angular donc une réponse React semble hors-sujet.

4 votes

Peu importe… il a plusieurs votes positifs, donc cette réponse a été utile pour d'autres.

1 votes

Fonctionne à merveille. onChange={(event: ChangeEvent): void => {setTextFilter(event.target.value);}}

10voto

belvederef Points 500

La façon dont je le fais est la suivante (meilleure que l'assertion de type à mon avis):

onFieldUpdate(event: { target: HTMLInputElement }) {
  this.$emit('onFieldUpdate', event.target.value);
}

Cela suppose que vous êtes seulement intéressé par la propriété target, 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 types &:

event: Event & { target: HTMLInputElement }

Il s'agit d'une version de Vue.js mais le concept s'applique à tous les frameworks. Bien sûr, vous pouvez être plus spécifique et au lieu d'utiliser un HTMLInputElement général, vous pouvez utiliser par exemple HTMLTextAreaElement pour les zones de texte.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X