A propriedade 'value' não existe no valor do tipo 'HTMLElement'


235

Estou brincando com o texto datilografado e tentando criar um script que atualize um elemento p à medida que o texto é inserido em uma caixa de entrada.

O html tem a seguinte aparência:

<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 o greeter.tsarquivo:

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

Ao compilar tsc, recebo o seguinte "erro":

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

No entanto, o compilador gera um arquivo javascript, que funciona bem no chrome.

Como obtenho esse erro? E como posso corrigir isso?

Além disso, onde posso procurar quais propriedades são válidas de 'HTMLElement'acordo com o texto datilografado?

Por favor, note que eu sou muito novo em javascript e texto datilografado; portanto, posso estar perdendo algo óbvio. :)

Respostas:


448

Com base na resposta de Tomasz Nurkiewiczs, o "problema" é que o texto datilografado é seguro. :) Portanto, document.getElementById()retorna o tipo HTMLElementque não contém uma valuepropriedade. O subtipo HTMLInputElement, no entanto, contém a valuepropriedade

Assim, uma solução é converter o resultado getElementById()da HTMLInputElementassim:

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

<>é o operador de conversão em texto datilografado. Veja a pergunta TypeScript: lançando HTMLElement .

O javascript resultante da linha acima é assim:

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

ou seja, não contendo informações de tipo.


você tem alguma lista de qual elemento do html pertence a qual tipo para o texto datilografado? se sim, então pls post será útil para alguém !! Obrigado pela ótima resposta.
precisa saber é o seguinte

1
Essa correção quebra completamente meu código; diz que o que vem a seguir "não é uma função". Não entendo o raciocínio por trás da maneira como o TS lida com isso; Como getElementById pode retornar qualquer tipo de elemento, qualquer um deve ser aceito por padrão.
Turtles Are Cute

@TurtlesAreCute Estou curioso para saber como essa solução quebrou seu código. Felizmente, um ano depois, você encontrou uma solução, mas a conversão para HTMLInputElement deveria ter funcionado.
Michaël Polla

No meu caso, tive que alterá-lo para HTMLAnchorElement.
Wildhammer

@ Wildhammer Porque o seu elemento não era um elemento de entrada! O OP é.
Auspex

68

Se você estiver usando o react, poderá usar o asoperador.

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

3
Por algum motivo, a resposta aceita aqui foi gerar o seguinte erro para mim: O elemento JSX 'HTMLInputElement' não possui uma marca de fechamento correspondente. Esta é a resposta que funcionou para mim.
NigelTufnel

1
O motivo é que, nos arquivos tsx, você não pode usar os <>operadores para transmitir, pois eles são usados ​​no React. Então você tem que usar como: basarat.gitbooks.io/typescript/docs/types/...
Powderham

Embora isso não funcionou para mim, ele me direcionou a direção certa :) voto positivo !!!
Simon Price

40

Tente converter o elemento que você deseja atualizar para HTMLInputElement. Conforme indicado nas outras respostas, você precisa sugerir ao compilador que este é um tipo específico de HTMLElement:

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


17

Uma solução rápida para isso é usar [] para selecionar o atributo.

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

Eu apenas tento alguns métodos e descubro esta solução,
não sei qual é o problema por trás do seu script original.

Para referência, consulte a publicação de Tomasz Nurkiewicz.


A resposta adequada à pergunta me ajudou muito.
Monor Khan

15

O problema está aqui:

document.getElementById(elementId).value

Você sabe que HTMLElementretornou de getElementById()é realmente uma instância de HTMLInputElementherdar porque está passando um ID do elemento de entrada. Da mesma forma, no Java estaticamente tipado, isso não será compilado:

public Object foo() {
  return 42;
}

foo().signum();

signum()é um método de Integer, mas o compilador conhece apenas o tipo estático de foo(), o que é Object. E Objectnão tem um signum()método.

Mas o compilador não pode saber disso, apenas pode basear-se em tipos estáticos, não no comportamento dinâmico do seu código. E, tanto quanto o compilador sabe, o tipo de document.getElementById(elementId)expressão não possui valuepropriedade. Apenas elementos de entrada têm valor.

Para uma referência, verifique HTMLElemente HTMLInputElementno MDN. Eu acho que o Typescript é mais ou menos consistente com isso.


Mas não estou acessando .valueno elemento p, estou acessando no inputelemento. Ou estou enganado?
Bjarke Freund-Hansen

1
@bjarkef: você está ligando document.getElementById("greet")e tem <p id="greet"></p>...
Tomasz Nurkiewicz

Estou chamando document.getElementById("greet").innerTextque deve ser perfeitamente válido, só estou acessando a valuepropriedade no elemento de entrada na linha que contém: var inputValue = document.getElementById(elementId).value;in greet(elementId)e que é chamada no html onkeyup="greet('name')"no formulário de entrada. Por isso, acho que você está interpretando mal o código. Corrija-me se estiver errado. :)
Bjarke Freund-Hansen

@ bjarkef: desculpe, você estava certo. Eu reescrevi minha resposta, dê uma olhada!
Tomasz Nurkiewicz 20/10/12

1
Ah, isso faz sentido. Então, devo converter o valor retornado getElementByIde como faço isso no texto datilografado? Ou existe outro método getElementByIdque retorne HTMLInputElement?
Bjarke Freund-Hansen

11

Também para quem usa propriedades como Props ou Refs sem o seu "DocgetId's", você pode:

("" as HTMLInputElement).value;

Onde as aspas invertidas são o valor dos seus props, um exemplo seria o seguinte:

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

4

Se você estiver usando angular, poderá usar -

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

1

Este trabalho para mim:

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

Precisa de formatação
Standin.Wolf 4/19

-1

Problema:

error A propriedade 'text' não existe no tipo 'HTMLElement'

Solução: à máquina precisamos elenco document.getElementById()que retorna tipo HTMLElementem< HTMLScriptElement >

Portanto, podemos fazer isso da seguinte maneira para resolver o erro conforme o esperado pelo typescript.js

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

Funcionou para mim .. espero que funcione para você também.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.