Comment vérifier le type d'une classe en TypeScript : du débutant au pro
\n\nAvez-vous déjà écrit du code en TypeScript, reçu un objet de type inconnu et pensé : « Mais qui es-tu, toi, en fait ? » ? Cette question hante des milliers de développeurs — ce n'est pas pour rien que le sujet class type check in TypeScript a rassemblé des centaines de milliers de vues sur Stack Overflow. Et aujourd'hui, nous allons une fois pour toutes comprendre comment vérifier correctement les types de classes en TypeScript.
\n\nDans cet article, vous apprendrez :
\n- \n
- Pourquoi
typeofne fonctionne pas pour les classes \n - Comment utiliser
instanceofcomme un couteau suisse \n - Ce que sont les type guards et comment ils sauvent votre code \n
- Comment écrire votre propre vérification de type avec
is\n - Des exemples concrets tirés de la pratique \n
C'est parti !
\n\nLe problème : pourquoi typeof est-il impuissant ici ?
\n\nEn JavaScript, il existe l'opérateur typeof, qui fonctionne parfaitement avec les primitives :
typeof "hello" // "string"\ntypeof 42 // "number"\ntypeof true // "boolean"\n\nMais quand il s'agit de classes, typeof capitule :
class Dog {}\nclass Cat {}\n\nconst pet = new Dog();\n\ntypeof pet; // "object" — inutile !\ntypeof Dog; // "function" — pas ça non plus\n\nPourquoi ? Parce que les classes en JavaScript ne sont que du sucre syntaxique autour des fonctions constructeurs. typeof ne voit que « object » ou « function », mais ne distingue pas de quelle classe il s'agit.
C'est là qu'intervient le class type check in TypeScript — tout un arsenal d'outils qui vous aidera à déterminer précisément avec l'instance de quelle classe vous avez affaire.
\n\nMéthode 1 : instanceof — votre principal assistant
\n\nLa manière la plus directe et la plus simple de vérifier le type d'une classe est l'opérateur instanceof. Il vérifie si la classe se trouve dans la chaîne de prototypes de l'objet :
class Animal {\n name: string;\n constructor(name: string) {\n this.name = name;\n }\n}\n\nclass Dog extends Animal {\n bark() {\n console.log("Woof!");\n }\n}\n\nclass Cat extends Animal {\n meow() {\n console.log("Meow!");\n }\n}\n\nfunction handleAnimal(animal: Animal) {\n if (animal instanceof Dog) {\n // TypeScript sait que animal est un Dog\n animal.bark();\n } else if (animal instanceof Cat) {\n animal.meow();\n } else {\n console.log(`Unknown animal: ${animal.name}`);\n }\n}\n\nconst rex = new Dog("Rex");\nhandleAnimal(rex); // "Woof!"\n\nRemarquez : après la vérification animal instanceof Dog, TypeScript réduit automatiquement le type (type narrowing) et permet d'appeler les méthodes de Dog sans erreur. C'est la magie des type guards — les gardiens de types intégrés.
Quand instanceof ne fonctionne-t-il pas ?
\n- \n
- Lorsqu'on travaille avec différentes fenêtres/cadres (objets globaux différents) \n
- Si les classes sont définies dans des modules différents avec des versions différentes \n
- Lors de la vérification d'interfaces (elles n'existent pas à l'exécution) \n
Méthode 2 : Type guards personnalisés avec l'opérateur is
\n\nParfois, instanceof ne suffit pas. Par exemple, vous voulez vérifier non seulement la classe, mais aussi des conditions supplémentaires. C'est là que les type guards personnalisés avec le mot-clé is viennent à la rescousse :
interface Bird {\n fly(): void;\n layEggs(): void;\n}\n\ninterface Fish {\n swim(): void;\n layEggs(): void;\n}\n\nfunction isFish(pet: Bird | Fish): pet is Fish {\n return (pet as Fish).swim !== undefined;\n}\n\nfunction move(pet: Bird | Fish) {\n if (isFish(pet)) {\n // TypeScript sait : pet est un Fish\n pet.swim();\n } else {\n pet.fly();\n }\n}\n\nRemarquez la syntaxe : pet is Fish dans le type de retour. Cela indique à TypeScript : « Si cette fonction retourne true, alors le paramètre pet est un Fish ». Désormais, TypeScript réduira le type partout où vous utili