Erro típico do TypeScript: property 'value' does not exist on HTMLElement

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

«A propriedade value não existe»: como fazer TypeScript e DOM se darem bem

\n\n

Você já escreveu um simples manipulador de formulário em TypeScript, executou a compilação — e recebeu uma linha vermelha no console: «The property 'value' does not exist on value of type 'HTMLElement'»? Se sim — você não está sozinho. Esta pergunta acumulou milhares de visualizações no Stack Overflow, e hoje vamos resolvê-la de uma vez por todas.

\n\n

O erro ocorre quando você tenta obter .value de um elemento que o TypeScript considera apenas como HTMLElement. O problema é que HTMLElement é um tipo base, e a propriedade value existe apenas em HTMLInputElement, HTMLTextAreaElement e seus descendentes. O TypeScript é rigoroso: ele não permite acessar uma propriedade que (do seu ponto de vista) não existe.

\n\n

Mas isso não é um bug — é uma funcionalidade. O TypeScript protege você de erros em tempo de execução. Vamos entender como especificar o tipo corretamente e, de quebra, melhorar o desempenho do seu código.

\n\n

Por que o TypeScript reclama?

\n\n

Imagine: você escreve código para um campo de entrada:

\n\n
const input = document.getElementById('myInput');\nconsole.log(input.value); // ❌ Erro!
\n\n

O método getElementById retorna o tipo HTMLElement | null. HTMLElement não tem a propriedade value. Ele tem innerHTML, className, style — mas não value. O TypeScript diz honestamente: «Não tenho certeza se este elemento tem value».

\n\n

Mas você tem certeza de que é um <input>. Como explicar isso ao compilador?

\n\n

Método 1: Type Assertion

\n\n

A maneira mais popular e rápida é usar as:

\n\n
const input = document.getElementById('myInput') as HTMLInputElement;\nconsole.log(input.value); // ✅ Funciona
\n\n

Agora o TypeScript sabe: é um HTMLInputElement, que tem value. Simples e eficaz. Mas há um detalhe: se o elemento não for realmente um <input> (por exemplo, for um <div>), você receberá undefined em tempo de execução. O TypeScript não vai ajudar — ele acredita nas suas afirmações.

\n\n

Método 2: Verificação de tipo com instanceof

\n\n

Uma abordagem mais segura é a verificação em tempo de execução:

\n\n
const element = document.getElementById('myInput');\nif (element instanceof HTMLInputElement) {\n    console.log(element.value); // ✅ TypeScript reduz o tipo automaticamente\n} else {\n    console.error('O elemento não é um input');\n}
\n\n

Este método não só resolve o problema de tipos, mas também torna o código mais confiável. Você verifica explicitamente se o elemento é exatamente o que espera. Para fins educacionais, recomendo este método: ele ensina a pensar sobre tipos.

\n\n

Método 3: Funções genéricas (Generics)

\n\n

Para usuários avançados — criação de um wrapper com genéricos:

\n\n
function getInputElement<T extends HTMLElement>(id: string): T | null {\n    const element = document.getElementById(id);\n    if (element instanceof T) { // ❌ Não funciona, T é um tipo, não um valor\n        return element;\n    }\n    return null;\n}
\n\n

Infelizmente, no TypeScript não é possível verificar instanceof com um genérico diretamente. Mas você pode usar sobrecarga de funções ou fábricas. Para projetos simples, os dois primeiros métodos são suficientes.

\n\n

Otimização de desempenho: por que o tipo importa

\n\n

Você pode perguntar: «Qual a relação dos tipos com a velocidade?» Direta. Quando o TypeScript sabe o tipo exato do elemento, ele gera código JavaScript mais eficiente. Vejamos um exemplo:

\n\n
// Ruim: TypeScript não sabe o tipo\nfunction getValue(id: string): string {\n    const el = document.getElementById(id);\n    // A cada chamada — verificação e type assertion\n    return (el as HTMLInputElement).value || '';\n}\n\n// Bo                

Blogs

Book Recommendations