Typescript: Demande de modification de currentTarget dans l'interface d'événement pour lib.d.ts

Créé le 29 juil. 2014  ·  36Commentaires  ·  Source: microsoft/TypeScript

Lors de l'utilisation de l'interface Event de lib.d.ts et de l'attachement d'un écouteur, le rappel obtiendra un objet de type Event. Cependant, la propriété currentTarget de l'événement est de type EventTarget (alors qu'elle devrait être de type Element / HTMLElement).

lib.d.ts Suggestion help wanted

Commentaire le plus utile

J'ai rencontré ce TS2339: Property 'result' does not exist on type 'EventTarget' dans JS FileReader onload , et un autre avertissement pour getSummary() sur l'événement passé au onerror de FileReader.

Ma solution pour supprimer les horribles lignes ondulées rouges ;-) est la suivante:

interface FileReaderEventTarget extends EventTarget {
    result:string
}

interface FileReaderEvent extends Event {
    target: FileReaderEventTarget;
    getMessage():string;
}

Puis dans mon appli:

reader.onload = function(fre:FileReaderEvent) {
        var data = JSON.parse(fre.target.result);
        ...
    }

Les codes JS générés semblent bons et fonctionnent pour moi. Ce type de solution, pour les types d'événements JS inhabituels, pourrait-il être ajouté à lib.d.ts?

Je suppose que ma solution est trop simpliste. Mais il serait utile de savoir pourquoi.

Tous les 36 commentaires

L'objet XMLHttpRequest peut également être currentTarget mais ce n'est pas Element / HTMLElement. C'est peut-être la raison derrière cela. Le type générique améliorerait-il cela?

interface Event<T extends EventTarget> {
    /* ... */
    currentTarget: T;
    /* ... */
}

interface EventListener<T extends EventTarget> {
    (evt: Event<T>): void;
}

interface HTMLElement {
    /* ... */
    addEventListener(type: string, listener: EventListener<HTMLElement>, useCapture?: boolean): void;
}

Il semble que cela contribuera grandement à l'améliorer.

Envoyé de mon iPhone

Le 3 août 2014, à 13h34, SaschaNaz [email protected] a écrit:

L'objet XMLHttpRequest peut également être currentTarget mais ce n'est pas Element / HTMLElement. C'est peut-être la raison derrière cela. Le type générique améliorerait-il cela?

Événement d'interface{
/ * ... _ /
currentTarget: T;
/ _ ... * /
}

interface EventListener{
(evt: événement): néant;
}

interface HTMLElement {
/ * ... * /
addEventListener (type: chaîne, écouteur: EventListener, useCapture?: booléen): void;
}
-
Répondez directement à cet e-mail ou affichez-le sur GitHub.

Notez que toutes les cibles d'événements ne sont pas des Element (http://www.w3.org/TR/DOM-Level-3-Events/#event-types), donc la solution ici devrait être plus dans le sens de la suggestion de

Le problème est que nous générons actuellement lib.d.ts, en utilisant un script, basé sur un fichier que nous ne pouvons pas rendre public pour le moment, et ce fichier est obsolète au profit d'un nouveau. Pour cette raison, nous n'allons pas apporter d'améliorations au script pour le moment, mais nous espérons que dans le futur nous pourrons prendre des PR sur le script / entrée de génération lib.d.ts.

Tagging «Revisit» pour le moment - veuillez nous envoyer un ping à ce sujet dans un mois et je pourrai voir où nous en sommes.

Existe-t-il une syntaxe pour faire référence au type actuel? Je pense que cela peut être résolu plus facilement si nous pouvons faire ce genre de travail:

interface HTMLElement {
    addEventListener(type: string, listener: EventListener<this>, useCapture?: boolean): void;
}

var image: HTMLImageElement;
var video: HTMLVideoElement;
image.addEventListener // receives EventListener<HTMLImageElement> type
video.addEventListener // receives EventListener<HTMLVideoElement> type

Cette fonctionnalité n'existe pas, c'est quelque chose qui ressemble à ce qui est suggéré dans les # 285 et # 229

Salut à tous, ping de ce fil. J'ai rencontré ce problème avec Event.target . J'imagine que la plupart du temps, une cible est un HTMLElement . Il est un peu étrange que le type par défaut suppose que ce n'est pas le cas. J'ai essayé la suggestion de @SaschaNaz et je suis tombé sur le problème d '"identifiant en double" (désolé il me manque peut-être quelque chose, je suis assez nouveau dans TypeScript).

Edit: cela a permis de calmer les avertissements: (<HTMLElement>event.target).tagName

@rayshan la suggestion portait sur ce qui devrait entrer dans le fichier lib.d.ts et le fichier est généré automatiquement en fonction directement de l'implémentation d'Internet Explorer. L'erreur que vous avez rencontrée est donc exacte. Pour le moment, le seul moyen de contourner ce problème est de construire sans la bibliothèque intégrée ( --noLib ) et d'utiliser la solution de contournement, ou de faire ce que vous avez fait, qui est converti en cible. Il existe actuellement un certain nombre de défis à relever pour gérer les types de retour du DOM en ce moment dans TypeScript (principalement parce que le DOM n'est pas l'ensemble d'API le plus cohérent / structuré / de type sûr / implémenté de manière cohérente).

Maintenant que le # 4910 est fusionné, peut-il être revisité?

@zhengbli peut avoir un contexte sur l'état des problèmes de lib.d.ts qui nécessitent une génération basée sur un script

PR les bienvenus. voici quelques informations sur la contribution aux modifications de lib.d.ts: https://github.com/Microsoft/TypeScript/blob/master/CONTRIBUTING.md#contributing -libdts-fixes

J'ai rencontré ce TS2339: Property 'result' does not exist on type 'EventTarget' dans JS FileReader onload , et un autre avertissement pour getSummary() sur l'événement passé au onerror de FileReader.

Ma solution pour supprimer les horribles lignes ondulées rouges ;-) est la suivante:

interface FileReaderEventTarget extends EventTarget {
    result:string
}

interface FileReaderEvent extends Event {
    target: FileReaderEventTarget;
    getMessage():string;
}

Puis dans mon appli:

reader.onload = function(fre:FileReaderEvent) {
        var data = JSON.parse(fre.target.result);
        ...
    }

Les codes JS générés semblent bons et fonctionnent pour moi. Ce type de solution, pour les types d'événements JS inhabituels, pourrait-il être ajouté à lib.d.ts?

Je suppose que ma solution est trop simpliste. Mais il serait utile de savoir pourquoi.

J'aimerais résoudre ce problème. Mais comme je le vois, la seule référence à currentTarget se trouve à l'intérieur des fichiers webworker.generated.d.ts générés dans le générateur TSJS. Je ne sais pas comment résoudre ce problème 😞
J'espère vraiment que quelqu'un pourrait résoudre ce problème vieux de près de 3 ans. De telles erreurs peuvent être la raison pour laquelle j'entends souvent les gens dire que TypeScript est difficile à utiliser et cela me rend vraiment triste.

Bien. J'ai essayé de commencer à résoudre ce problème. Je crée un PR https://github.com/Microsoft/TSJS-lib-generator/pull/202
Espérons que cela va dans la bonne direction.

Je reçois Property 'getBoundingClientRect' does not exist on type 'EventTarget'. . Je pense que c'est une bonne idée.

Eh bien, le PR est en attente depuis près de 2 mois. J'examinerai ceci s'il y a quelque chose qui pourrait être fait pour accélérer ceci.

Ce serait vraiment génial si nous pouvions avoir currentTarget générique, de sorte que par exemple HTMLInputElement.onchange puisse être de type (event: Event<HTMLInputElement>) => void sorte que event.currentTarget.value fonctionne sans aucun cast ou tapez des annotations. Les typages de React le font, mais malheureusement pas dom.lib.d.ts.

Ceci est bloqué par un problème de performance causé par les génériques car l'introduction des génériques double l'utilisation de la mémoire 😭

Ces problèmes de performances s'appliquent-ils également aux typages React?

lib.d.ts n'inclut pas les typages React mais vous pouvez le tester en ajoutant --diagnostics à la commande.

@felixfbecker Je doute personnellement que cela soit corrigé bientôt. Je suppose que la plupart des gens ont déjà créé leur solution de contournement ou abandonné TypeScript. C'est aussi pourquoi il y a si peu de gens qui rencontrent ce problème.

Ce problème existe toujours dans la version 1.18.0 (1.18.0)

Bonjour,

Même problème avec ... et je suppose que ce n'est pas encore résolu.

quand je marque mon projet angular 4 pour la production, alors le problème apparaît, sinon, alors que je n'utilise que ng serve .. cela fonctionne très bien. Donc, je suppose qu'il y a quelque chose lié à la façon dont angular gère les fichiers de production.

J'espère des progrès sur cette question. Il est difficile de manipuler dom avec Typescript.

Ce problème a quatre ans et le PR correspondant près d'un an, je doute que cela soit résolu de sitôt.

Ce problème existe depuis 4 ans mais n'a pas encore été résolu.

Un correctif est disponible sur https://github.com/Microsoft/TSJS-lib-generator/pull/207
Mais @saschanaz bloque en fonction des performances.

Casting party tonite at 11 - déchargez les onglets de votre navigateur:
confirmationMessage(event: BeforeUnloadEvent): any {
const activeElement: HTMLElement = <HTMLElement>(<Document>event.target).activeElement;

: dancing_men:

Qu'en est-il d'ajouter

    readonly currentTarget: Element | null;
    readonly target: Element | null;

sur UIEvent seulement? Ce n'est pas très spécifique, mais rend la plupart du code heureux.
Peut-être même sans | null comme sur un UIEvent, les deux sont toujours définis

même problème ici. J'essayais d'utiliser Vue avec Typescript et je voulais obtenir la valeur d'un champ de saisie lorsque l'utilisateur tapait. Mais event.target.value ne passerait pas le vérificateur de type même si - je pense - une entrée de texte doit toujours produire de tels champs pour un tel événement

Nous nous sommes débarrassés de l'erreur en ajoutant le type any à notre code:

this.url = (<any>event).target.result;

Qu'en est-il de taper Event et EventTarget?

interface Event<C = any, S = any, T = any> {
  ...
  currentTarget: EventTarget<C> | null;
  srcElement: EventTarget<S> | null;
  target: EventTarget<T> | null;
  ...
}

interface EventTarget<T = any> {
  ...
}

J'ai rencontré ce problème lors de l'utilisation de FileReader, un simple cast vers le type correct le corrige

const fileReader = new FileReader();
fileReader.onload = $ev => {
  console.log($ev); // type ProgressEvent
  console.log($ev.target); // type FileReader
  // console.log($ev.target.result); // editor and autocomplete doesn't show any error
  console.log(($ev.target as FileReader).result); // casting compiles fine
};
fileReader.readAsText(file);

Y a-t-il des mises à jour sur ce sujet? Il serait utile de l'avoir sans forcer le casting event.target chaque fois ou tout événement de casting (comme @gautamkrishnar l'a fait ci-dessus). C'est aussi ouvert depuis 2014. Merci!

En effet, ce serait bien avec une sorte de réponse officielle à ce problème avant son 6e anniversaire

Oui, c'est probablement la nuisance numéro 1 d'une journée lorsque vous travaillez avec DOM, JSX, etc.

En fait, c'est la seule nuisance quotidienne que j'ai - et j'imagine qu'un million de personnes en souffrent toute la journée.

Il est vraiment difficile de comprendre pourquoi cela n'a aucune priorité.

Idem pour event.target. Un scénario très courant consiste à ajouter un gestionnaire de clics à un élément parent lorsque les enfants n'existent pas encore et lorsqu'il y aura de nombreux enfants. Un simple test pour event.target.tagName ou même classList est une chose courante que je fais. Cela fonctionne ... je l'ai utilisé pendant de nombreuses années. Je n'obtiens pas d'intellisense pour tagName / classList car EventTarget n'est pas classé comme HTMLElement, mais cela fonctionne.

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

kyasbal-1994 picture kyasbal-1994  ·  3Commentaires

fwanicka picture fwanicka  ·  3Commentaires

Roam-Cooper picture Roam-Cooper  ·  3Commentaires

siddjain picture siddjain  ·  3Commentaires

Antony-Jones picture Antony-Jones  ·  3Commentaires