« Type 'string' is not assignable to type » — qu'est-ce que c'est et pourquoi vous êtes ici ?
\n\nSi vous avez déjà codé en TypeScript, vous avez forcément vu un soulignement rouge dans votre éditeur avec ce message :
\n\nType 'string' is not assignable to type 'SomeType'.\n\nCette erreur est un véritable « bonjour » du typage strict. Elle effraie les débutants, mais en réalité, c'est la meilleure amie du développeur. Dans cet article, nous allons décortiquer pourquoi l'erreur Type 'string' is not assignable to type se produit, comment la corriger et quelles approches utiliser pour travailler avec les littéraux de chaîne, les types union et les génériques. Cet article est rédigé pour le site éducatif pythonlib.ru, mais les exemples sont exclusivement en TypeScript.
\n\n1. La racine du problème : pourquoi TypeScript râle-t-il sur les chaînes ?
\n\nTypeScript est une surcouche de JavaScript qui ajoute le typage statique. Lorsque vous écrivez :
\n\nlet role: 'admin' | 'user' = 'admin';\nrole = 'moderator'; // Erreur : Type '"moderator"' is not assignable to type '"admin" | "user"'\n\n\nTypeScript comprend que la variable role ne peut prendre que deux valeurs : 'admin' ou 'user'. Quand vous essayez d'assigner 'moderator', le compilateur génère une erreur. Mais pourquoi écrit-il « Type 'string' is not assignable to type » ?
En réalité, le littéral de chaîne 'moderator' a le type string, alors que le type attendu est 'admin' | 'user'. TypeScript compare les types, pas les valeurs. Il voit : « Tu me donnes une chaîne ordinaire, mais j'attends des chaînes spécifiques ». D'où le message.
1.1. Un exemple simple pour comprendre
\n\nPrenons un cas de base :
\n\ntype Status = 'active' | 'inactive';\n\nfunction updateStatus(status: Status) {\n console.log(status);\n}\n\nconst myStatus = 'active';\nupdateStatus(myStatus); // OK\n\nconst anotherStatus = 'pending';\nupdateStatus(anotherStatus); // Erreur : Type 'string' is not assignable to type 'Status'\n\n\nDans le dernier cas, la variable anotherStatus est inférée comme string, et non comme 'pending'. TypeScript ne sait pas que 'pending' est un littéral. Il ne voit que le type string. Pour corriger cela, il suffit de préciser le type explicitement :
const anotherStatus: 'pending' = 'pending'; // Maintenant ça fonctionne\n\n\n2. Comparaison des approches : comment contourner ou corriger l'erreur
\n\nIl existe plusieurs façons de gérer l'erreur Type 'string' is not assignable to type. Comparons-les en termes de simplicité, de sécurité et de performance.
\n\n2.1. Approche 1 : as const — geler le littéral
\n\nLa méthode la plus élégante consiste à utiliser as const. Cela « gèle » la valeur en tant que littéral :
const myStatus = 'active' as const;\nupdateStatus(myStatus); // OK\n\n\nAvantages : simple, lisible, sûr.
\nInconvénients : fonctionne uniquement avec const, pas avec let.
2.2. Approche 2 : Type Assertion (as) — conversion explicite
\n\nVous pouvez dire à TypeScript : « Je sais ce que je fais » :
\n\nconst someString: string = 'active';\nupdateStatus(someString as Status); // OK\n\n\nAvantages : solution rapide.
\nInconvénients : vous désactivez la vérification de type. Si vous passez une valeur incorrecte, l'erreur n'apparaîtra qu'à l'exécution.
2.3. Approche 3 : Type Guard (garde de type)
\n\nÉcrivons une fonction qui vérifie si une chaîne est un statut valide :
\n\nfunction isStatus(value: string): value is Status {\n return value === 'active' || value === 'inactive';\n}\n\nfunction safeUpdate(value: string) {\n if (isStatus(value)) {\n updateStatus(value); // TypeScript sait que value est de type Status\n } else {\n throw new Error('Statut invalide');\n }\n}\n