La proprietà 'valore' non esiste sul valore di tipo 'HTMLElement'


235

Sto giocando con il dattiloscritto e sto cercando di creare uno script che aggiornerà un elemento p man mano che il testo viene inserito in una casella di input.

Il codice HTML è simile al seguente:

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

E il greeter.tsfile:

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

Quando compilo con tscottengo il seguente "errore":

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

Tuttavia, il compilatore genera un file javascript, che funziona bene in Chrome.

Come mai ricevo questo errore? E come posso ripararlo?

Inoltre, dove posso cercare quali proprietà sono valide su un 'HTMLElement'secondo dattiloscritto?

Nota che sono molto nuovo su JavaScript e dattiloscritto, quindi potrei mancare qualcosa di ovvio. :)

Risposte:


448

Sulla base della risposta di Tomasz Nurkiewicz, il "problema" è che il dattiloscritto è dattiloscritto. :) Quindi document.getElementById()restituisce il tipo HTMLElementche non contiene una valueproprietà. Il sottotipo HTMLInputElementcontiene tuttavia la valueproprietà.

Quindi una soluzione è lanciare il risultato getElementById()in HTMLInputElementquesto modo:

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

<>è l'operatore di casting in dattiloscritto. Vedi la domanda TypeScript: casting HTMLElement .

Il javascript risultante dalla riga sopra è simile al seguente:

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

cioè non contiene informazioni sul tipo.


hai qualche elenco a quale elemento di HTML appartiene per quale tipo di dattiloscritto? se sì, ti preghiamo di inviarlo per qualcuno !! Grazie per la magnifica risposta.
Pardeep Jain,

1
Questa correzione rompe del tutto il mio codice; dice qualunque cosa venga dopo "non è una funzione". Non capisco il ragionamento alla base di come TS gestisce questo; poiché getElementById può restituire qualsiasi tipo di elemento, ognuno dovrebbe essere accettato per impostazione predefinita.
tartarughe sono carine il

@TurtlesAreCute Sono curioso di sapere come questa soluzione ha violato il tuo codice. Eventualmente un anno dopo hai trovato una soluzione, ma il casting su HTMLInputElement avrebbe dovuto funzionare.
Michaël Polla,

Nel mio caso, ho dovuto cambiarlo in HTMLAnchorElement.
Wildhammer,

@Wildhammer Perché il tuo elemento non era un elemento Input! L'OP è.
Auspex,

68

Se si utilizza reagire, è possibile utilizzare l' asoperatore.

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

3
Per qualche motivo, la risposta accettata qui stava generando il seguente errore per me: l'elemento JSX 'HTMLInputElement' non ha tag di chiusura corrispondente. Questa è la risposta che ha funzionato per me.
NigelTufnel,

1
Il motivo è perché nei file tsx non è possibile utilizzare gli <>operatori per eseguire il cast, poiché questi sono utilizzati in React. Quindi devi usare come: basarat.gitbooks.io/typescript/docs/types/…
Powderham

Anche se questo non ha funzionato per me, mi ha indirizzato nella giusta direzione :) voto positivo !!!
Simon Price,

40

Prova a trasmettere l'elemento che desideri aggiornare a HTMLInputElement. Come indicato nelle altre risposte, è necessario indicare al compilatore che si tratta di un tipo specifico di HTMLElement:

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


17

Una soluzione rapida per questo è usare [] per selezionare l'attributo.

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

Provo solo alcuni metodi e scopro questa soluzione,
non so quale sia il problema dietro il tuo script originale.

Per riferimento si può fare riferimento al post di Tomasz Nurkiewicz.


La risposta corretta alla domanda, mi ha aiutato molto.
Monir Khan,

15

Il problema è qui:

document.getElementById(elementId).value

Sai che HTMLElementrestituito da getElementById()è in realtà un'istanza di HTMLInputElementeredità da esso perché stai passando un ID di elemento di input. Allo stesso modo in Java tipicamente statico questo non verrà compilato:

public Object foo() {
  return 42;
}

foo().signum();

signum()è un metodo di Integer, ma il compilatore conosce solo il tipo statico di foo(), che è Object. E Objectnon ha un signum()metodo.

Ma il compilatore non può saperlo, può solo basarsi su tipi statici, non sul comportamento dinamico del codice. E per quanto ne sa il compilatore, il tipo di document.getElementById(elementId)espressione non ha valueproprietà. Solo gli elementi di input hanno valore.

Per un controllo di riferimento HTMLElemente HTMLInputElementin MDN. Immagino che Typescript sia più o meno coerente con questi.


Ma non accedo .valueall'elemento p, accedo inputall'elemento. O mi sbaglio?
Bjarke Freund-Hansen,

1
@bjarkef: stai chiamando document.getElementById("greet")e hai <p id="greet"></p>...
Tomasz Nurkiewicz

Sto chiamando document.getElementById("greet").innerTextche dovrebbe essere perfettamente valido, accedo solo alla valueproprietà sull'elemento input nella riga contenente: var inputValue = document.getElementById(elementId).value;in greet(elementId)e che viene chiamato nell'html onkeyup="greet('name')"nel modulo di input. Quindi penso che tu stia leggendo male il codice, per favore correggimi se sbaglio. :)
Bjarke Freund-Hansen,

@bjarkef: scusa, avevi ragione. Ho riscritto la mia risposta, dai un'occhiata!
Tomasz Nurkiewicz,

1
Ah, questo ha senso. Quindi dovrei trasmettere il valore restituito getElementByIde come posso farlo in dattiloscritto? O c'è un altro metodo di quello getElementByIdche ritorna HTMLInputElement?
Bjarke Freund-Hansen,

11

Inoltre, per chiunque utilizzi proprietà come oggetti di scena o riferimenti senza "DocgetId", puoi:

("" as HTMLInputElement).value;

Dove le virgolette sono il valore dei tuoi oggetti di scena, quindi un esempio potrebbe essere così:

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

4

Se stai usando angolare puoi usare -

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

1

Questo lavoro per me:

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

Richiede formattazione
Standin.Wolf

-1

Problema:

errore La proprietà 'testo' non esiste sul tipo 'HTMLElement'

Soluzione: a macchina abbiamo bisogno di fusione document.getElementById()che restituisce tipo HTMLElementin< HTMLScriptElement >

Quindi possiamo farlo seguendo il modo di risolvere l'errore come previsto da typescript.js

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

Ha funzionato per me .. spero che funzioni anche per te.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.