Свойство 'value' не существует по значению типа 'HTMLElement'

Я играю с typescript и пытаюсь создать script, который будет обновлять p-элемент, поскольку текст вводится в поле ввода.

html выглядит следующим образом:

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

И файл 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);
}

Когда я компилирую с помощью tsc, я получаю следующую "ошибку":

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

Однако компилятор выводит файл javascript, который отлично работает в chrome.

Как я могу получить эту ошибку? И как я могу это исправить?

Кроме того, где я могу посмотреть, какие свойства действительны на 'HTMLElement' в соответствии с typescript?

Обратите внимание, что я очень новичок в javascript и typescript, поэтому я мог бы пропустить что-то очевидное.:)

Ответ 1

На основании ответа Томаша Нуркевича "проблема" заключается в том, что typescript является типичным.:) Итак, document.getElementById() возвращает тип HTMLElement, который не содержит свойство value. Однако подтип HTMLInputElement содержит свойство value.

Итак, решение состоит в том, чтобы передать результат getElementById() в HTMLInputElement следующим образом:

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

<> - оператор литья в typescript. См. Вопрос TypeScript: литье HTMLElement.

Полученный javascript из строки выше выглядит следующим образом:

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

то есть. не содержащий информации о типе.

Ответ 2

Попробуйте выбрать элемент, который вы хотите обновить, в HTMLInputElement. Как указано в других ответах, вам нужно указать компилятору, что это определенный тип HTMLElement:

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

Ответ 3

Проблема здесь:

document.getElementById(elementId).value

Вы знаете, что HTMLElement, возвращенный из getElementById(), фактически является экземпляром HTMLInputElement, наследующим от него, потому что вы передаете идентификатор элемента ввода. Аналогично в статически типизированной Java это не будет компилироваться:

public Object foo() {
  return 42;
}

foo().signum();

signum() - это метод Integer, но компилятор знает только статический тип foo(), который равен Object. И Object не имеет метода signum().

Но компилятор не может этого знать, он может базироваться только на статических типах, а не на динамическом поведении вашего кода. И, насколько известно компилятору, тип выражения document.getElementById(elementId) не имеет свойства value. Только входные элементы имеют значение.

Для справки HTMLElement и HTMLInputElement в MDN. Я думаю, Typescript более или менее согласуется с ними.

Ответ 4

Если вы используете реакцию, вы можете использовать оператор as.

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

Ответ 5

Быстрое исправление для этого - использование [] для выбора атрибута.

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

Я просто попробую несколько методов и узнаю это решение,
Я не знаю, в чем проблема с вашим оригинальным script.

Для справки вы можете обратиться к сообщению Томаша Нуркевича.

Ответ 6

Проблема:

error Свойство "текст" не существует в типе "HTMLElement"

Решение: в typeScript нам нужно указать document.getElementById(), который возвращает тип HTMLElement в < HTMLScriptElement >

Таким образом, мы можем сделать это путем следующего способа разрешения ошибки, как ожидается, с помощью typescript.js

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

Это сработало для меня.. надеюсь, что это сработает и для вас.