Type never en TypeScript : comment corriger l'erreur "not assignable to parameter"

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

Introduction : pourquoi TypeScript crie-t-il sur un tableau vide ?

\n\n

Avez-vous déjà écrit du code en TypeScript, lancé la compilation, et reçu un message mystérieux : "Argument of type 'X' is not assignable to parameter of type 'never'" ? Si oui, vous n'êtes pas seul. Cette erreur est un véritable obstacle pour les développeurs de tous niveaux. Sur Stack Overflow, cette question a recueilli des milliers de vues, et aujourd'hui nous allons l'analyser une fois pour toutes.

\n\n

Imaginez la situation : vous déclarez un tableau vide, essayez d'y ajouter quelque chose, et TypeScript bloque l'opération. Cela vous dit quelque chose ? Voyons pourquoi cela se produit et, surtout, comment le corriger.

\n\n

Dans cet article, nous ne nous contenterons pas de traduire une documentation aride. Nous suivrons le chemin depuis l'apparition de l'erreur jusqu'à sa résolution complète avec des exemples concrets que vous pourrez immédiatement appliquer dans vos projets.

\n\n

Qu'est-ce que le type never en TypeScript ?

\n\n

Avant de plonger dans les méandres des erreurs, comprenons le type never lui-même. En TypeScript, ce type désigne "une valeur qui ne peut pas exister". Cela semble philosophique, mais en pratique c'est simple :

\n\n
    \n
  • never est le type pour les fonctions qui ne se terminent jamais (boucle infinie) ou qui lèvent toujours une exception.
  • \n
  • never est le "fond" du système de types. Vous pouvez assigner never à n'importe quoi, mais rien ne peut être assigné à never (sauf never lui-même).
  • \n
\n\n

Imaginez maintenant que TypeScript voit un tableau vide et ne sait pas quels éléments il contiendra. En mode de typage strict (strict: true dans tsconfig.json), le compilateur fait une déduction logique : "Si le tableau est vide et que le type n'est pas spécifié, alors rien ne peut s'y trouver — le type des éléments est never".

\n\n
// Exemple : TypeScript déduit le type comme never[]\nconst emptyArray = [];\nemptyArray.push("hello"); // Erreur !\n// Argument of type 'string' is not assignable to parameter of type 'never'\n
\n\n

Voilà, c'est cette fameuse erreur. TypeScript vous avertit honnêtement : "Tu as dit que le tableau ne peut contenir que never, mais tu essayes d'ajouter une chaîne. Ça ne marche pas !"

\n\n

Scénarios principaux d'apparition de l'erreur

\n\n

1. Tableau vide sans annotation de type

\n\n

Le cas le plus fréquent. Le développeur crée un tableau vide, prévoyant de le remplir plus tard, mais oublie de spécifier le type.

\n\n
// ❌ Problème\nconst items = []; // TypeScript déduit : any[] (si strict: false) ou never[] (si strict: true)\nitems.push({ id: 1, name: "Alice" }); // Erreur avec strict: true\n\n// ✅ Solution : spécifiez explicitement le type\nconst items: Array<{ id: number; name: string }> = [];\nitems.push({ id: 1, name: "Alice" }); // Fonctionne !\n
\n\n

2. Méthodes de tableau retournant never (filter, reduce)

\n\n

La méthode filter avec un prédicat incorrect ou reduce sans valeur initiale peuvent conduire à une déduction du type never.

\n\n
// ❌ Problème avec filter\nconst numbers: (number | null)[] = [1, null, 2, null, 3];\nconst onlyNumbers = numbers.filter(item => item !== null); \n// TypeScript peut déduire le type comme (number | null)[] ou même never[], si le prédicat est "cassé"\n\n// ✅ Solution : utilisez un type guard\nconst onlyNumbersSafe: number[] = numbers.filter((item): item is number => item !== null); \n\n// ❌ Problème avec reduce\nconst result = [1, 2, 3].reduce((acc, val) => acc + val); \n// Erreur ! TypeScript ne connaît pas le type initial de l'accumulateur\n\n// ✅ Solution : spécifiez la valeur initiale\nconst resultSafe = [1, 2, 3].reduce((acc, val) => acc + val, 0); // Fonctionne !\n
\n\n

3. Génériques et types conditionnels

\n\n

Un cas plus complexe — lorsque TypeScript ne peut pas déduire le type en raison de génériques complexes.

\n\n
// ❌ Problème\nfunction getFirstElement<T>(arr: T[]): T | undefined {\n  return arr[0];\n}\n\nfunction processItems<T>                

Blogs

Book Recommendations