Właściwość „wartość” nie istnieje dla wartości typu „HTMLElement”


235

Bawię się pismem maszynowym i próbuję utworzyć skrypt, który aktualizuje element p, gdy tekst jest wprowadzany w polu wprowadzania.

HTML wygląda następująco:

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

A greeter.tsplik:

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

Podczas kompilacji pojawia tscsię następujący „błąd”:

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

Jednak kompilator generuje plik javascript, który działa dobrze w chrome.

Jak mogę uzyskać ten błąd? Jak mogę to naprawić?

Ponadto, gdzie mogę sprawdzić, które właściwości są poprawne na 'HTMLElement'podstawie pisma maszynowego?

Pamiętaj, że jestem bardzo nowy w javascript i maszynopisie, więc może mi brakować czegoś oczywistego. :)

Odpowiedzi:


448

Na podstawie odpowiedzi Tomasza Nurkiewicza „problemem” jest to, że maszynopis jest bezpieczny. :) document.getElementById()Zwraca więc typ, HTMLElementktóry nie zawiera valuewłaściwości. Podtyp HTMLInputElementzawiera jednak valuewłaściwość.

Tak więc rozwiązaniem jest rzutowanie wyniku getElementById()na HTMLInputElementnastępujący:

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

<>jest operatorem rzutowania w maszynopisie. Zobacz pytanie TypeScript: casting HTMLElement .

Powstały javascript z powyższej linii wygląda następująco:

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

tzn. nie zawiera informacji o typie.


Czy masz listę, który element HTML należy do jakiego typu dla maszynopisu? jeśli tak, to proszę o wysłanie wiadomości. dzięki za świetną odpowiedź.
Pardeep Jain

1
Ta poprawka całkowicie łamie mój kod; mówi, że cokolwiek będzie dalej „nie jest funkcją”. Nie rozumiem powodów, dla których TS sobie z tym radzi; ponieważ getElementById może zwrócić dowolny typ elementu, każdy powinien być domyślnie zaakceptowany.
Turtles Are Cute

@TurtlesAreCute Jestem ciekawy, jak to rozwiązanie złamało Twój kod. Mam nadzieję, że rok później znalazłeś rozwiązanie, ale rzutowanie na HTMLInputElement powinno było działać.
Michaël Polla

W moim przypadku musiałem zmienić go na HTMLAnchorElement.
Wildhammer,

@Wildhammer Ponieważ twój element nie był elementem wejściowym! OP jest.
Auspex

68

Jeśli używasz reagowania, możesz użyć asoperatora.

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

3
Z jakiegoś powodu zaakceptowana tutaj odpowiedź wywołała dla mnie następujący błąd: element JSX „HTMLInputElement” nie ma odpowiedniego znacznika zamykającego. To była odpowiedź, która zadziałała dla mnie.
NigelTufnel

1
Powodem jest to, że w plikach tsx nie można używać <>operatorów do przesyłania , ponieważ są one używane w React. Musisz więc użyć jako: basarat.gitbooks.io/typescript/docs/types/…
Powderham

Chociaż to nie zadziałało, skierowało mnie w dobrym kierunku :) głosuj w górę !!!
Simon Price

40

Spróbuj rzutować element, który chcesz zaktualizować, na HTMLInputElement. Jak stwierdzono w innych odpowiedziach, musisz wskazać kompilatorowi, że jest to określony typ HTMLElement:

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


17

Szybkim rozwiązaniem tego jest użycie [], aby wybrać atrybut.

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

Wypróbowałem tylko kilka metod i znalazłem to rozwiązanie,
nie wiem na czym polega problem z twoim oryginalnym skryptem.

W celach informacyjnych możesz odnieść się do postu Tomasza Nurkiewicza.


Prawidłowa odpowiedź na pytanie bardzo mi pomogła.
Monir Khan,

15

Problem jest tutaj:

document.getElementById(elementId).value

Wiesz, że HTMLElementzwrócone z getElementById()jest w rzeczywistości instancją HTMLInputElementdziedziczenia po nim, ponieważ przekazujesz identyfikator elementu wejściowego. Podobnie w statycznie wpisanej Javie nie będzie to kompilować:

public Object foo() {
  return 42;
}

foo().signum();

signum()jest metodą Integer, ale kompilator zna tylko typ statyczny foo(), którym jest Object. I Objectnie ma signum()metody.

Ale kompilator nie może tego wiedzieć, może opierać się tylko na typach statycznych, a nie na dynamicznym zachowaniu kodu. I o ile kompilator wie, typ document.getElementById(elementId)wyrażenia nie ma valuewłaściwości. Tylko elementy wejściowe mają wartość.

Do kontroli referencyjnej HTMLElementoraz HTMLInputElementw MDN. Chyba maszynopis jest z nimi mniej więcej zgodny.


Ale nie uzyskuję dostępu .valuedo elementu p, uzyskuję do niego dostęp w tym inputelemencie. Czy się mylę?
Bjarke Freund-Hansen

1
@bjarkef: dzwonisz document.getElementById("greet")i masz <p id="greet"></p>...
Tomasz Nurkiewicz

Wywołuję, document.getElementById("greet").innerTextco powinno być całkowicie poprawne, uzyskuję dostęp tylko do valuewłaściwości elementu wejściowego w wierszu zawierającym: var inputValue = document.getElementById(elementId).value;in greet(elementId)i to jest wywoływane w HTML onkeyup="greet('name')"w formularzu wejściowym. Więc myślę, że źle odczytujesz kod, popraw mnie, jeśli się mylę. :)
Bjarke Freund-Hansen

@bjarkef: przepraszam, miałeś rację. Przepisałem swoją odpowiedź, spójrz!
Tomasz Nurkiewicz,

1
Ach, to ma sens. Czy więc powinienem rzutować wartość zwróconą getElementByIdi jak to zrobić w maszynopisie? A może jest inna metoda niż getElementByIdta zwraca HTMLInputElement?
Bjarke Freund-Hansen

11

Również dla każdego, kto używa właściwości takich jak rekwizyty lub referencje bez twojego „DocgetId's”, możesz:

("" as HTMLInputElement).value;

Gdzie odwrócone cudzysłowy są wartością twoich rekwizytów, przykład może wyglądać tak:

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

4

Jeśli używasz kątowego, możesz użyć -

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


-1

Problem:

błąd Właściwość „tekst” nie istnieje dla typu „HTMLElement”

Rozwiązanie: w maszynopisie musimy obsady document.getElementById(), która zwraca typ HTMLElementw< HTMLScriptElement >

Możemy to zrobić, postępując zgodnie z oczekiwaniami w pliku scriptcript.js

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

Dla mnie to zadziałało. Mam nadzieję, że również dla ciebie.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.