Introduction : « Type 'string | undefined' is not assignable to type 'string' » — une douleur familière ?
\n\nSi vous écrivez en TypeScript depuis au moins une semaine, vous avez forcément vu ce message. Il apparaît au moment le plus inattendu : vous êtes sûr que la variable est une chaîne, mais le compilateur insiste obstinément : « Hé, il pourrait y avoir undefined ici ! ». Ça vous parle ?
Cette erreur est l'une des questions les plus fréquentes sur Stack Overflow (des milliers de vues, des dizaines de réponses). Et ce n'est pas parce que TypeScript « bugue ». Au contraire : il vous sauve de bugs à l'exécution qui pourraient faire planter l'application. Mais comment l'expliquer au compilateur ? Comment rendre le code à la fois sûr et lisible ?
\n\nDans cet article, nous allons voir :
\n- \n
- Pourquoi l'erreur
Type 'string | undefined' is not assignable to type 'string'se produit \n - 5 méthodes pour la corriger (de la plus simple à la plus avancée) \n
- Les pièges typiques des débutants \n
- Quand utiliser
!(non-null assertion) et quand préférer??(nullish coalescing) \n
Prêts ? C'est parti !
\n\n1. Pourquoi cette erreur se produit-elle en TypeScript ?
\n\nEn JavaScript, une variable peut être undefined à tout moment. TypeScript, surtout avec le flag strictNullChecks activé, veut que vous indiquiez explicitement : « Je sais qu'il peut y avoir du vide ici, et je le gère ».
Regardez cet exemple simple :
\n\nfunction getUsername(id: number): string {\n const user = users.find(u => u.id === id);\n return user.name; // Erreur ! user peut être undefined\n}\n\n\nLa méthode find() retourne User | undefined. Si l'utilisateur n'est pas trouvé, elle retourne undefined. TypeScript le voit et crie : « Tu essaies d'assigner string | undefined à string ! Interdit ! ».
Ce n'est pas un bug de TypeScript, c'est une fonctionnalité. Il vous oblige à réfléchir : « Et si l'utilisateur n'existe pas ? Que retournera la fonction ? Une chaîne vide ? Une erreur ? ». Et c'est une bonne chose.
\n\n2. 5 méthodes pour corriger l'erreur (de la plus simple à la plus complexe)
\n\n2.1. L'opérateur Non-null assertion (!)
\n\nLa méthode la plus rapide (et la plus dangereuse) est de dire à TypeScript : « Tais-toi, je sais ce que je fais ».
\n\nfunction getUsername(id: number): string {\n const user = users.find(u => u.id === id);\n return user!.name; // ! — je suis sûr que user n'est pas undefined\n}\n\n\nQuand l'utiliser : Uniquement si vous êtes absolument certain que la valeur existe. Par exemple, si vous venez d'ajouter cet utilisateur au tableau et que vous savez que find le trouvera.
Quand NE PAS l'utiliser : Dans 90% des cas. C'est comme désactiver l'airbag d'une voiture — ça marche, mais le risque est énorme.
\n\n2.2. Vérification avec if (type guard)
\n\nLa méthode classique et sûre :
\n\nfunction getUsername(id: number): string {\n const user = users.find(u => u.id === id);\n if (user) {\n return user.name; // TypeScript sait : à l'intérieur du bloc, user est bien User\n }\n return 'Invité'; // fallback\n}\n\n\nTypeScript est intelligent : après la vérification if (user), il « réduit » le type. À l'intérieur du bloc, user est de type User, et non User | undefined.
2.3. L'opérateur de chaînage optionnel (?.) avec fallback
\n\nUne ligne élégante pour travailler avec des objets imbriqués :
\n\nfunction getUsername(id: number): string {\n const user = users.find(u => u.id === id);\n return user?.name ?? 'Invité';\n}\n\n\nDétaillons pas à pas :
\n- \n
user?.name— siuserestundefined, retourneundefinedsans générer d'erreur \n ?? 'Invité'— si la valeur à gauche estundefinedounull, on utilise 'Invité' \