Властивість '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, який добре працює в хромі.

Як я можу отримати цю помилку? І як я можу це виправити?

Крім того, де я можу шукати, які властивості є дійсними 'HTMLElement'відповідно до машинопису?

Зауважте, що я дуже новачок у JavaScript та typecript, тому я можу пропустити щось очевидне. :)

Відповіді:


448

Виходячи з відповіді Томаша Нуркевича, "проблема" полягає в тому, що машинопис є typesafe. :) Отже, document.getElementById()повертає тип, HTMLElementякий не містить valueвластивості. Однак підтип HTMLInputElementмістить valueвластивість.

Таким чином, рішення кинути результат з getElementById()до HTMLInputElementтак:

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

<>є оператором кастингу в typecript. Дивіться питання TypeScript: лиття HTMLElement .

Отриманий Javascript із рядка вище виглядає так:

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

тобто не містить інформації про тип.


чи є у вас список, до якого типу HTML належить тип, для якого пишеться? якщо так, то, будь ласка, повідомлення, це буде корисним для когось !! дякую за чудову відповідь.
— Pardeep Jain

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

@TurtlesAreCute Мені цікаво, як це рішення зламало ваш код. Сподіваємось, через рік ви знайшли рішення, але кастинг на HTMLInputElement мав би спрацювати.
— Michaël Polla

У моєму випадку мені довелося змінити його на HTMLAnchorElement.
— Wildhammer

@Wildhammer Оскільки ваш елемент не був елементом Input! ОП є.
— Auspex

68

Якщо ви використовуєте react, ви можете скористатися 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елементі. Або я помиляюся?
— Bjarke Freund-Hansen

1
@bjarkef: ти дзвониш document.getElementById("greet")і маєш <p id="greet"></p>...
— Tomasz Nurkiewicz

Я дзвоню, document.getElementById("greet").innerTextщо повинно бути абсолютно дійсним, я отримую доступ лише до valueвластивості елемента введення в рядку, що містить: var inputValue = document.getElementById(elementId).value;in, greet(elementId)що викликається у html onkeyup="greet('name')"у формі введення. Тому я думаю, що ви неправильно читаєте код, будь ласка, виправте мене, якщо я помиляюся. :)
— Bjarke Freund-Hansen

@bjarkef: Вибачте, ви мали рацію. Я переписав свою відповідь, подивіться!
— Томаш Нуркевич

1
Ах, це має сенс. Тож чи повинен я відкинути значення, повернене звідти, getElementByIdі як це зробити в машинопис? Або є інший метод, ніж getElementByIdтой, що повертаєтьсяHTMLInputElement ?
— Bjarke Freund-Hansen

11

Також для тих, хто використовує такі властивості, як Реквізит або Відношення без вашого "DocgetId", ви можете:

("" as HTMLInputElement).value;

Якщо перевернуті лапки - це значення реквізиту, такий приклад виглядає так:

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

4

Якщо ви використовуєте кутовий, ви можете використовувати -

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


-1

Проблема:

помилка Властивість 'текст' не існує для типу 'HTMLElement'

Рішення: машинопис ми повинні гіпс , document.getElementById()який повертає тип HTMLElementв< HTMLScriptElement >

Таким чином, ми можемо це зробити, дотримуючись наступного способу вирішити помилку, як очікувалося від typecript.js

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

Це працювало для мене .. сподіваюся, що він працює і для вас.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.