Je joue avec TypeScript et j'essaie de créer un script qui mettra à jour un élément p lorsque le texte est entré dans une zone de saisie.
Le HTML ressemble à ce qui suit:
<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 fichier greeter.ts
:
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 tsc
, le message d'erreur suivant s'affiche:
/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 en chrome.
Comment puis-je avoir cette erreur? Et comment puis-je la corriger?
De plus, où puis-je rechercher quelles propriétés sont valides sur un 'HTMLElement'
selon le manuscrit?
Notez que javascript et TypeScript étant nouveaux pour moi, il se peut que je manque quelque chose d’évident. :)
Basé sur la réponse de Tomasz Nurkiewiczs, le "problème" est que TypeScript est typé. :) Ainsi, la document.getElementById()
renvoie le type HTMLElement
qui ne contient pas de propriété value
. Le sous-type HTMLInputElement
contient cependant la propriété value
.
Donc, une solution consiste à convertir le résultat de getElementById()
en HTMLInputElement
comme ceci:
var inputValue = (<HTMLInputElement>document.getElementById(elementId)).value;
<>
est l'opérateur de transtypage dans TypeScript. Voir la question TypeScript: casting 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.
Si vous utilisez Réagissez, vous pouvez utiliser l'opérateur as
.
let inputValue = (document.getElementById(elementId) as HTMLInputElement).value;
Essayez de transtyper l'élément que vous souhaitez mettre à jour vers 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);
Le problème est ici:
document.getElementById(elementId).value
Vous savez que HTMLElement
renvoyé par getElementById()
est en réalité une instance de HTMLInputElement
qui en hérite, car vous transmettez un ID d'élément d'entrée. De même dans 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 Object
n'a pas de méthode signum()
.
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 de l'expression document.getElementById(elementId)
n'a pas la propriété value
. Seuls les éléments d'entrée ont une valeur.
Pour une vérification de référence HTMLElement
et HTMLInputElement
dans MDN. Je suppose que TypeScript est plus ou moins compatible avec ceux-ci.
Une solution rapide pour cela consiste à 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);
}
Je viens d'essayer quelques méthodes et trouver 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.
Exemple mis à jour:
const inputElement: HTMLInputElement = document.getElementById('greet') as HTMLInputElement
const inputValue: string = InputElement.value
Documentation:
Aussi, pour toute personne utilisant des propriétés telles que des accessoires ou des références sans votre "DocgetId", vous pouvez:
("" as HTMLInputElement).value;
Où les guillemets inversés sont la valeur de vos accessoires, un exemple serait comme ceci:
var val = (this.refs.newText as HTMLInputElement).value;
alert("Saving this:" + val);