Erreur TypeScript typique : property 'value' does not exist on HTMLElement

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

« La propriété value n'existe pas » : comment faire collaborer TypeScript et le DOM

\n\n

Avez-vous déjà écrit un simple gestionnaire de formulaire en TypeScript, lancé la compilation — et obtenu dans la console une ligne rouge : « The property 'value' does not exist on value of type 'HTMLElement' » ? Si oui, vous n'êtes pas seul. Cette question a rassemblé des milliers de vues sur Stack Overflow, et aujourd'hui nous allons l'analyser une fois pour toutes.

\n\n

L'erreur se produit lorsque vous essayez d'obtenir .value d'un élément que TypeScript considère simplement comme HTMLElement. Le problème est que HTMLElement est un type de base, alors que la propriété value n'existe que sur HTMLInputElement, HTMLTextAreaElement et leurs descendants similaires. TypeScript est strict : il ne vous permettra pas d'accéder à une propriété qui n'existe pas (de son point de vue).

\n\n

Mais ce n'est pas un bug — c'est une fonctionnalité. TypeScript vous protège des erreurs d'exécution. Voyons comment spécifier correctement le type et, par la même occasion, améliorer les performances de votre code.

\n\n

Pourquoi TypeScript se plaint-il ?

\n\n

Imaginez : vous écrivez du code pour un champ de saisie :

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

La méthode getElementById retourne le type HTMLElement | null. HTMLElement n'a pas de propriété value. Il a innerHTML, className, style — mais pas value. TypeScript dit honnêtement : « Je ne suis pas sûr que cet élément ait une propriété value ».

\n\n

Pourtant, vous êtes sûr qu'il s'agit d'un <input>. Comment l'expliquer au compilateur ?

\n\n

Méthode 1 : Cast de type (Type Assertion)

\n\n

La méthode la plus populaire et la plus rapide consiste à utiliser as :

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

Maintenant, TypeScript sait : c'est un HTMLInputElement, qui a une propriété value. Simple et efficace. Mais il y a un détail : si l'élément n'est pas réellement un <input> (par exemple, c'est un <div>), vous obtiendrez undefined à l'exécution. TypeScript ne vous aidera pas — il croit vos affirmations.

\n\n

Méthode 2 : Vérification de type avec instanceof

\n\n

Une approche plus sûre consiste à vérifier lors de l'exécution :

\n\n
const element = document.getElementById('myInput');\nif (element instanceof HTMLInputElement) {\n    console.log(element.value); // ✅ TypeScript réduit automatiquement le type\n} else {\n    console.error('L\'élément n\'est pas un input');\n}
\n\n

Cette méthode non seulement résout le problème de typage, mais rend également le code plus fiable. Vous vérifiez explicitement que l'élément est bien celui attendu. À des fins pédagogiques, je recommande cette méthode : elle apprend à réfléchir aux types.

\n\n

Méthode 3 : Fonctions génériques (Generics)

\n\n

Pour les utilisateurs avancés — création d'une enveloppe avec des génériques :

\n\n
function getInputElement<T extends HTMLElement>(id: string): T | null {\n    const element = document.getElementById(id);\n    if (element instanceof T) { // ❌ Impossible, T est un type, pas une valeur\n        return element;\n    }\n    return null;\n}
\n\n

Malheureusement, en TypeScript, on ne peut pas vérifier instanceof directement avec un générique. Mais on peut utiliser des surcharges de fonctions ou des fabriques. Pour les projets simples, les deux premières méthodes suffisent.

\n\n

Optimisation des performances : pourquoi le type est important

\n\n

Vous pourriez demander : « Quel rapport les types ont-ils avec la vitesse ? » Direct. Lorsque TypeScript connaît le type exact d'un élément, il génère un code JavaScript plus efficace. Prenons un exemple :

\n\n
// Mauvais : TypeScript ne connaît pas le type\nfunction getValue(id: string): string {\n    const el = document.getElementById(id);\n    // À chaque appel — vérification et cast\n    return (el as HTMLInputElement).value || '';\n}\n\n// Bo                

Blogs

Book Recommendations