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


235

Я играю с машинописью и пытаюсь создать скрипт, который будет обновлять 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'соответствии с машинописью?

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

Ответы:


448

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

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

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

<>является оператором приведения в машинописи. Смотрите вопрос TypeScript: приведение HTMLElement .

Результирующий JavaScript из строки выше выглядит так:

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

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


У вас есть список, какой элемент HTML принадлежит к какому типу для машинописи? если да, то, пожалуйста, пост будет полезно для кого-то !! спасибо за отличный ответ.
Пардип Джейн

1
Это исправление полностью нарушает мой код; говорит, что будет дальше "не является функцией". Я не понимаю причины того, как TS справляется с этим; поскольку getElementById может возвращать любой тип элемента, любой должен быть принят по умолчанию.
Черепахи милые

@TurtlesAreCute Мне интересно, как это решение сломало ваш код. Надеюсь, через год вы нашли решение, но приведение к HTMLInputElement должно было сработать.
Микаэль Полла

В моем случае мне пришлось изменить его на HTMLAnchorElement.
Wildhammer

@Wildhammer Потому что ваш элемент не был элементом ввода! ОП есть.
Auspex

68

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

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

3
По какой-то причине принятый здесь ответ вызвал для меня следующую ошибку: у элемента JSX 'HTMLInputElement' нет соответствующего закрывающего тега. Это ответ, который работал для меня.
NigelTufnel

1
Причина в том, что в файлах TSX нельзя использовать <>операторы для приведения, поскольку они используются в React. Так что вы должны использовать как: basarat.gitbooks.io/typescript/docs/types/…
Powderham

Хотя это не сработало для меня, оно направило меня в правильном направлении :) голосование !!!
Саймон Прайс

40

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

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


17

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

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

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

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


Правильный ответ на вопрос, мне очень помог.
Монир Хан

15

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

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 более или менее соответствует этим.


Но у меня нет доступа .valueк элементу p, я обращаюсь к нему по inputэлементу. Или я ошибаюсь?
Бьярке Фрейнд-Хансен

1
@bjarkef: вы звоните, document.getElementById("greet")и у вас есть <p id="greet"></p>...
Томаш Нуркевич

Я звоню, document.getElementById("greet").innerTextкоторый должен быть совершенно действительным, я только получаю доступ к valueсвойству элемента input в строке, содержащей: var inputValue = document.getElementById(elementId).value;in, greet(elementId)и это вызывается в html onkeyup="greet('name')"в форме ввода. Поэтому я думаю, что вы неправильно читаете код, пожалуйста, исправьте меня, если я ошибаюсь. :)
Бьярке Фрейнд-Хансен

@bjarkef: извини, ты был прав. Я переписал свой ответ, посмотрите!
Томаш Нуркевич

1
Ах, это имеет смысл. Так я должен привести значение, возвращаемое из, getElementByIdи как мне сделать это в машинописи? Или есть другой метод, чем getElementByIdэто возвращает HTMLInputElement?
Бьярке Фрейнд-Хансен

11

Также для тех, кто использует свойства, такие как Props или Refs без вашего «DocgetId's», вы можете:

("" as HTMLInputElement).value;

Где перевернутые кавычки - это значение вашего реквизита, поэтому пример будет таким:

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

4

Если вы используете угловой, вы можете использовать -

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


-1

Проблема:

Свойство error 'text' не существует для типа 'HTMLElement'

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

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

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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.