Die Eigenschaft 'Wert' ist für den Wert vom Typ 'HTMLElement' nicht vorhanden.


233

Ich spiele mit Typoskript herum und versuche, ein Skript zu erstellen, das ein p-Element aktualisiert, wenn Text in ein Eingabefeld eingegeben wird.

Das HTML sieht wie folgt aus:

<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>

Und das greeter.ts Datei:

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);
}

Wenn ich mit kompiliere tsc erhalte ich folgenden "Fehler":

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

Der Compiler gibt jedoch eine Javascript-Datei aus, die in Chrome einwandfrei funktioniert.

Wie kommt es, dass ich diesen Fehler bekomme? Und wie kann ich das beheben?

Wo kann ich nachschlagen, welche Eigenschaften für a gültig sind? 'HTMLElement' Typoskript ?

Bitte beachten Sie, dass ich mit Javascript und Typoskript sehr neu bin, sodass mir möglicherweise etwas Offensichtliches fehlt. :) :)

Antworten:


446

Basierend auf der Antwort von Tomasz Nurkiewicz ist das "Problem", dass Typoskript typsicher ist. :) Das document.getElementById()gibt also den Typ zurück, HTMLElementder keine valueEigenschaft enthält. Der Subtyp HTMLInputElemententhält jedoch dievalue Eigenschaft.

Eine Lösung besteht also darin, das Ergebnis so getElementById()zu gestalten HTMLInputElement:

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

<>ist der Casting-Operator in Typoskript. Siehe die Frage TypeScript: Casting von HTMLElement .

Das resultierende Javascript aus der obigen Zeile sieht folgendermaßen aus:

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

dh ohne Typinformationen.


Haben Sie eine Liste, welches HTML-Element zu welchem ​​Typ für das Typoskript gehört? Wenn ja, dann bitte posten, es wird für jemanden hilfreich sein !! danke für die tolle antwort.
Pardeep Jain

1
Dieser Fix bricht meinen Code vollständig; sagt, was als nächstes kommt "ist keine Funktion". Ich verstehe die Gründe für die Art und Weise, wie TS damit umgeht, nicht. Da getElementById jeden Elementtyp zurückgeben kann, sollte jeder standardmäßig akzeptiert werden.
Schildkröten sind süß

@TurtlesAreCute Ich bin gespannt, wie diese Lösung Ihren Code gebrochen hat. Hoffentlich haben Sie ein Jahr später eine Lösung gefunden, aber das Casting in HTMLInputElement hätte funktionieren sollen.
Michaël Polla

In meinem Fall musste ich es in HTMLAnchorElement ändern.
Wildhammer

@ Wildhammer Weil dein Element kein Eingabeelement war ! Das OP ist.
Auspex

68

Wenn Sie "Reagieren" verwenden, können Sie den asOperator verwenden.

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

3
Aus irgendeinem Grund hat die hier akzeptierte Antwort den folgenden Fehler für mich ausgelöst: Das JSX-Element 'HTMLInputElement' hat kein entsprechendes schließendes Tag. Dies ist die Antwort, die für mich funktioniert hat.
NigelTufnel

1
Der Grund dafür ist, dass Sie in tsx-Dateien die <>Operatoren nicht zum Umwandeln verwenden können , da diese in React verwendet werden. Sie müssen also Folgendes
Powderham

Obwohl dies bei mir nicht funktioniert hat, hat es mich in die richtige Richtung gelenkt :) up stimmen !!!
Simon Price

40

Versuchen Sie, das Element, das Sie aktualisieren möchten, in HTMLInputElement umzuwandeln. Wie in den anderen Antworten angegeben, müssen Sie dem Compiler mitteilen, dass dies ein bestimmter Typ von HTMLElement ist:

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


17

Eine schnelle Lösung hierfür ist die Verwendung von [] zur Auswahl des Attributs.

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

Ich probiere nur ein paar Methoden aus und finde diese Lösung heraus.
Ich weiß nicht, was das Problem hinter Ihrem ursprünglichen Skript ist.

Als Referenz können Sie sich auf den Beitrag von Tomasz Nurkiewicz beziehen.


Die richtige Antwort auf die Frage hat mir sehr geholfen.
Monir Khan

15

Das Problem ist hier:

document.getElementById(elementId).value

Sie wissen, dass HTMLElementvon zurückgekehrtgetElementById() tatsächlich eine Instanz des HTMLInputElementErbens ist, da Sie eine ID des Eingabeelements übergeben. Ähnlich wird dies in statisch typisiertem Java nicht kompiliert:

public Object foo() {
  return 42;
}

foo().signum();

signum()ist eine Methode von Integer, aber der Compiler kennt nur den statischen Typ vonfoo() , nämlich Object. Und Objecthat keinesignum() Methode.

Der Compiler kann das jedoch nicht wissen. Er kann nur auf statischen Typen basieren, nicht auf dem dynamischen Verhalten Ihres Codes. Und soweit der Compiler weiß, hat die Art des document.getElementById(elementId)Ausdrucks nichtvalue Eigenschaft. Nur Eingabeelemente haben Wert.

Für eine Referenzprüfung HTMLElementund HTMLInputElementin MDN. Ich denke, Typescript stimmt mehr oder weniger mit diesen überein.


Aber ich greife nicht .valueauf das p-Element zu, sondern auf das inputElement. Oder irre ich mich?
Bjarke Freund-Hansen

1
@bjarkef: Sie rufen an document.getElementById("greet")und Sie haben <p id="greet"></p>...
Tomasz Nurkiewicz

Ich rufe auf, document.getElementById("greet").innerTextwas vollkommen gültig sein sollte. Ich greife nur auf die valueEigenschaft des Eingabeelements in der Zeile zu, die Folgendes enthält: var inputValue = document.getElementById(elementId).value;in greet(elementId)und die im HTML-Code onkeyup="greet('name')"im Eingabeformular aufgerufen wird . Ich denke, Sie haben den Code falsch gelesen. Bitte korrigieren Sie mich, wenn ich falsch liege. :)
Bjarke Freund-Hansen

@bjarkef: Entschuldigung, Sie hatten Recht. Ich habe meine Antwort umgeschrieben, schau mal!
Tomasz Nurkiewicz

1
Ah, das macht Sinn. Soll ich den zurückgegebenen Wert umwandeln getElementByIdund wie mache ich das in Typoskript? Oder gibt es eine andere Methode als getElementByIddiese zurückgibt HTMLInputElement?
Bjarke Freund-Hansen

11

Auch für alle, die Eigenschaften wie Requisiten oder Refs ohne Ihre "DocgetId" verwenden, können Sie:

("" as HTMLInputElement).value;

Wo die invertierten Anführungszeichen Ihr Requisitenwert sind, wäre ein Beispiel wie folgt:

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

4

Wenn Sie eckig verwenden, können Sie verwenden -

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

1

Diese Arbeit für mich:

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

Benötigt Formatierung
Standin.Wolf

-1

Problem:

Fehler Die Eigenschaft 'text' ist für den Typ 'HTMLElement' nicht vorhanden.

Lösung: In typeScript müssen wir umwandeln, document.getElementById()was type HTMLElementin zurückgibt< HTMLScriptElement >

Wir können dies also folgendermaßen tun, um den von typescript.js erwarteten Fehler zu beheben

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

Es hat bei mir funktioniert. Ich hoffe, es funktioniert auch bei Ihnen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.