Propriétés dynamiques des objets en TypeScript : explication pour débutants

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

Comment assigner dynamiquement des propriétés à un objet en TypeScript ? Explication claire pour débutants

\n\n

Salut, l'ami ! Si tu as déjà écrit en JavaScript, puis migré vers TypeScript, tu as sûrement rencontré une situation où tu dois ajouter une nouvelle propriété à un objet à la volée. En JS, cela se fait en deux temps : obj.newProp = 'value'. Mais dès que tu essaies la même chose en TypeScript, le compilateur se met à râler : "Property 'newProp' does not exist on type ...". Ça te dit quelque chose ?

\n\n

Ne t'inquiète pas, c'est normal. TypeScript nous protège des erreurs accidentelles, mais parfois sa rigueur semble excessive. Dans cet article, nous allons voir comment assigner dynamiquement des propriétés aux objets de manière correcte et sécurisée. Tu découvriras plusieurs méthodes éprouvées – des plus simples aux plus élégantes. C'est parti !

\n\n

Pourquoi TypeScript râle-t-il ?

\n\n

Avant de résoudre le problème, comprenons sa racine. TypeScript est une surcouche de JavaScript qui ajoute le typage statique. Lorsque tu déclares un objet :

\n\n
const user = { name: 'Анна', age: 25 };\n
\n\n

TypeScript déduit automatiquement son type : { name: string; age: number }. Cela signifie que l'objet user ne peut contenir que ces deux propriétés. Essayer d'ajouter email provoquera une erreur de compilation :

\n\n
user.email = 'anna@example.com'; // ❌ Erreur !\n
\n\n

TypeScript ne sait pas qu'une telle propriété peut apparaître et bloque le code. Mais dans la vraie vie, on a souvent besoin d'ajouter des propriétés dynamiquement – par exemple, lorsqu'on travaille avec des données provenant d'une API ou de formulaires. Voyons comment faire cela correctement.

\n\n

Méthode 1 : La plus simple — as any

\n\n

Une méthode rapide mais sale consiste à utiliser as any. Elle dit littéralement à TypeScript : « Désactive la vérification de type pour cet objet ».

\n\n
const user: any = { name: 'Анна', age: 25 };\nuser.email = 'anna@example.com'; // ✅ Fonctionne\nuser.isAdmin = true;             // ✅ Fonctionne\n
\n\n

Pourquoi est-ce mauvais ? Parce que tu perds tous les avantages de TypeScript : l'autocomplétion, la vérification des types, la protection contre les fautes de frappe. Si tu écris accidentellement user.emial, il n'y aura pas d'erreur – tu ne le sauras qu'à l'exécution. Utilise cette méthode uniquement pour un prototypage rapide ou lorsque tu sais exactement ce que tu fais.

\n\n

Méthode 2 : La signature d'index (Index Signature)

\n\n

Une approche plus correcte consiste à déclarer à l'avance que l'objet peut contenir des propriétés dynamiques. Pour cela, on utilise une signature d'index.

\n\n
interface User {\n  name: string;\n  age: number;\n  [key: string]: any; // 👈 Permet toutes les propriétés supplémentaires\n}\n\nconst user: User = { name: 'Анна', age: 25 };\nuser.email = 'anna@example.com'; // ✅ Fonctionne\nuser.phone = '+7-999-123-45-67'; // ✅ Fonctionne\n
\n\n

Que se passe-t-il ici ? L'écriture [key: string]: any signifie : « l'objet peut avoir n'importe quelle clé de type chaîne, et ses valeurs peuvent être de n'importe quel type ». Maintenant, tu peux ajouter des propriétés dynamiquement, et TypeScript ne râlera pas.

\n\n

Nuance importante : si tu veux limiter les types de valeurs, remplace any par un type spécifique :

\n\n
interface User {\n  name: string;\n  age: number;\n  [key: string]: string | number; // Uniquement des chaînes et des nombres\n}\n
\n\n

La signature d'index est un excellent choix lorsque tu sais à l'avance que l'objet va s'étendre. Mais attention : si l'interface contient d'autres propriétés avec d'autres types, elles doivent aussi correspondre à la signature.

\n\n

Méthode 3 : Le type utilitaire Record

\n\n

Si tu as besoin de créer un objet où toutes les clés et toutes les valeurs sont du même type, utilise le type intégré Record<Keys, Type>. Il est parfait pour les dictionnaires ou les mappings.

\n\n
type UserRoles = Record<string, 'admin' | 'user' | 'guest'>;\n\nconst roles: UserRoles = {\n  anna: 'admin',\n  ivan: 'user',\n};\                

Blogs

Book Recommendations