La propriété 'value' n'existe pas sur la valeur de type 'HTMLElement'


235

Je joue avec dactylographié et j'essaie de créer un script qui mettra à jour un élément p à mesure que le texte est entré dans une zone de saisie.

Le html ressemble à ceci:

<html>
    <head>
    </head>
    <body>
        <p id="greet"></p>
        <form>
            <input id="name" type="text" name="name" value="" onkeyup="greet('name')" />
        </form>
    </body>
    <script src="greeter.js"></script>
</html>

Et le greeter.tsdossier:

function greeter(person)
{
    return "Hello, " + person;
}

function greet(elementId)
{
    var inputValue = document.getElementById(elementId).value;

    if (inputValue.trim() == "")
        inputValue = "World";

    document.getElementById("greet").innerText = greeter(inputValue);
}

Lorsque je compile avec, tscj'obtiens l '"erreur" suivante:

/home/bjarkef/sandbox/greeter.ts(8,53): The property 'value' does not exist on value of type 'HTMLElement'

Cependant, le compilateur génère un fichier javascript, qui fonctionne très bien dans Chrome.

Comment se fait-il que j'obtienne cette erreur? Et comment puis-je le réparer?

De plus, où puis-je rechercher quelles propriétés sont valides sur un 'HTMLElement'selon le typage?

Veuillez noter que je suis très nouveau sur javascript et dactylographié, donc il se peut que je manque quelque chose d'évident. :)

Réponses:


448

Sur la base de la réponse de Tomasz Nurkiewiczs, le "problème" est que le dactylographe est de type sécurisé. :) Ainsi, le document.getElementById()retourne le type HTMLElementqui ne contient pas de valuepropriété. Le sous HTMLInputElement- type contient cependant la valuepropriété.

Ainsi , une solution est de jeter le résultat de getElementById()la HTMLInputElementmanière suivante:

var inputValue = (<HTMLInputElement>document.getElementById(elementId)).value;

<>est l'opérateur de casting en tapuscrit. Voir la question TypeScript: cast HTMLElement .

Le javascript résultant de la ligne ci-dessus ressemble à ceci:

inputValue = (document.getElementById(elementId)).value;

c'est-à-dire ne contenant aucune information de type.


Avez-vous une liste à laquelle appartient l'élément HTML pour quel type de script? si oui, veuillez poster ce sera utile pour quelqu'un !! merci pour la bonne réponse.
— Pardeep Jain

1
Cette correction rompt entièrement mon code; dit que ce qui vient ensuite "n'est pas une fonction". Je ne comprends pas le raisonnement derrière la façon dont TS gère cela; puisque getElementById peut renvoyer n'importe quel type d'élément, tout doit être accepté par défaut.
— tortues sont mignonnes

@TurtlesAreCute Je suis curieux de savoir comment cette solution a cassé votre code. Avec un peu de chance, un an plus tard, vous avez trouvé une solution, mais la conversion vers HTMLInputElement aurait dû fonctionner.
— Michaël Polla

Dans mon cas, j'ai dû le changer en HTMLAnchorElement.
— Wildhammer

@Wildhammer Parce que votre élément n'était pas un élément Input! Le PO est.
— Auspex

68

Si vous utilisez React, vous pouvez utiliser l' asopérateur.

let inputValue = (document.getElementById(elementId) as HTMLInputElement).value;

3
Pour une raison quelconque, la réponse acceptée ici soulevait l'erreur suivante pour moi: l'élément JSX 'HTMLInputElement' n'a pas de balise de fermeture correspondante. C'est la réponse qui a fonctionné pour moi.
— NigelTufnel

1
La raison en est que dans les fichiers tsx, vous ne pouvez pas utiliser les <>opérateurs pour caster, car ils sont utilisés dans React. Vous devez donc utiliser comme: basarat.gitbooks.io/typescript/docs/types/…
— Powderham

Bien que cela n'ait pas fonctionné pour moi, cela m'a orienté dans la bonne direction :) vote up !!!
— Simon Price

40

Essayez de caster l'élément que vous souhaitez mettre à jour en HTMLInputElement. Comme indiqué dans les autres réponses, vous devez indiquer au compilateur qu'il s'agit d'un type spécifique de HTMLElement:

var inputElement = <HTMLInputElement>document.getElementById('greet');
inputElement.value = greeter(inputValue);


17

Une solution rapide est d'utiliser [] pour sélectionner l'attribut.

function greet(elementId) {
    var inputValue = document.getElementById(elementId)["value"];
    if(inputValue.trim() == "") {
        inputValue = "World";
    }
    document.getElementById("greet").innerText = greeter(inputValue);
}

J'essaye juste quelques méthodes et découvre cette solution,
je ne sais pas quel est le problème derrière votre script original.

Pour référence, vous pouvez vous référer au message de Tomasz Nurkiewicz.


Une bonne réponse à la question m'a beaucoup aidé.
— Monir Khan

15

Le problème est ici:

document.getElementById(elementId).value

Vous savez que HTMLElementretourné depuis getElementById()est en fait une instance de l' HTMLInputElementhéritage car vous passez un ID d'élément d'entrée. De même en Java statiquement typé, cela ne compilera pas:

public Object foo() {
  return 42;
}

foo().signum();

signum()est une méthode de Integer, mais le compilateur ne connaît que le type statique de foo(), qui est Object. Et Objectn'a pas de signum()méthode.

Mais le compilateur ne peut pas le savoir, il ne peut se baser que sur des types statiques, pas sur le comportement dynamique de votre code. Et pour autant que le compilateur le sache, le type d' document.getElementById(elementId)expression n'a pas de valuepropriété. Seuls les éléments d'entrée ont une valeur.

Pour une vérification des références HTMLElementet HTMLInputElementdans MDN. Je suppose que Typescript est plus ou moins cohérent avec ceux-ci.


Mais je n'y accède pas .valuesur l'élément p, j'y accède sur l' inputélément. Ou je me trompe?
— Bjarke Freund-Hansen,

1
@bjarkef: vous appelez document.getElementById("greet")et vous avez <p id="greet"></p>...
— Tomasz Nurkiewicz

J'appelle document.getElementById("greet").innerTextce qui devrait être parfaitement valide, j'accède uniquement à la valuepropriété sur l'élément d'entrée à la ligne contenant: var inputValue = document.getElementById(elementId).value;in greet(elementId)et qui est appelée dans le html onkeyup="greet('name')"dans le formulaire d'entrée. Je pense donc que vous avez mal lu le code, veuillez me corriger si je me trompe. :)
— Bjarke Freund-Hansen

@bjarkef: désolé, vous aviez raison. J'ai réécrit ma réponse, regarde!
— Tomasz Nurkiewicz

1
Ah, cela a du sens. Alors, dois-je convertir la valeur renvoyée par getElementByIdet comment puis-je le faire en tapant Ou existe-t-il une autre méthode que getElementByIdcelle qui revient HTMLInputElement?
— Bjarke Freund-Hansen

11

Aussi pour toute personne utilisant des propriétés telles que des accessoires ou des références sans vos «DocgetId», vous pouvez:

("" as HTMLInputElement).value;

Où les guillemets inversés sont la valeur de vos accessoires, un exemple ressemblerait à ceci:

var val = (this.refs.newText as HTMLInputElement).value;
alert("Saving this:" + val);

4

Si vous utilisez angulaire, vous pouvez utiliser -

const element = document.getElementById('elemId') as HTMLInputElement;

1

Ce travail pour moi:

let inputValue = (swal.getPopup().querySelector('#inputValue ')as HTMLInputElement).value

Besoin de mise en forme
— Standin.Wolf

-1

Problème:

erreur La propriété 'text' n'existe pas sur le type 'HTMLElement'

Solution: dans typeScript, nous devons convertir document.getElementById()qui renvoie le type HTMLElementdans< HTMLScriptElement >

Nous pouvons donc le faire en suivant la manière de résoudre l'erreur comme prévu par typescript.js

Code: var content: string = ( < HTMLScriptElement > document.getElementById(contentId)).text;

Cela a fonctionné pour moi .. j'espère que cela fonctionne aussi pour vous.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.