ProgrammationDéveloppeur Backend

Comment implémenter la surcharge des méthodes dans les classes TypeScript, quelles erreurs faut-il éviter lors de l'écriture de méthodes surchargées et quelles subtilités liées à la typage peuvent survenir ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

Historique de la question:

TypeScript prend en charge la surcharge des méthodes, comme d'autres langages à typage strict (par exemple, Java ou C#), cependant la syntaxe de surcharge en TypeScript diffère conceptuellement. Ici, plusieurs signatures sont autorisées, mais une seule implémentation est nécessaire. Cela peut prêter à confusion pour les développeurs familiers avec la surcharge classique.

Problème:

Une erreur courante consiste à essayer de définir plusieurs méthodes avec différents ensembles de paramètres. Cela entraîne une erreur de compilation, car TypeScript exige une implémentation qui réalise toutes les variantes de signatures.

Solution:

La surcharge est réalisée en déclarant plusieurs signatures de méthode, puis une implémentation qui correspond à toutes les variantes. Pour une distinction correcte des paramètres, on utilise généralement des gardiens de type ou instanceof.

Exemple de code :

class MyLogger { log(message: string): void; log(message: string, level: 'info' | 'error'): void; log(message: string, level?: 'info' | 'error'): void { const lvl = level ?? 'info'; console.log(`[${lvl}] ${message}`); } }

Caractéristiques clés :

  • Une seule implémentation de la méthode, mais plusieurs déclarations-signatures
  • Il faut assurer le traitement de toutes les variantes des paramètres d'entrée dans l'implémentation
  • Les types dans l'implémentation doivent être aussi larges que possible

Questions piégeuses.

Est-il possible d'implémenter deux implémentations d'une même méthode avec différents ensembles de paramètres ?

Non. En TypeScript, une seule implémentation est autorisée. Plusieurs méthodes avec le même nom entraînent une erreur de syntaxe.

Comment typiser les paramètres rest lors de la surcharge des méthodes, pour ne pas perdre le typage strict ?

Il est recommandé de décrire les paramètres exacts dans les signatures, et dans l'implémentation, d'utiliser les types les plus généraux :

class Test { doWork(a: number): void; doWork(a: string): void; doWork(a: number | string): void { //... } }

Que se passe-t-il si le type de retour des signatures surchargées est différent ?

TypeScript exigera que l'implémentation retourne un type union. Sinon, une erreur de compilation se produira.

class X { get(value: number): string; get(value: string): number; get(value: number | string): string | number { return typeof value === 'number' ? 'number' : 42; } }

Erreurs typiques et anti-modèles

  • Non-conformité de l'implémentation avec les signatures de surcharge
  • Plusieurs implémentations séparées d'une même méthode
  • Ignorer la vérification des types des paramètres d'entrée dans le corps de la méthode

Exemple de la vie

Cas négatif

Dans le produit, des tentatives ont été faites pour implémenter deux méthodes avec le même nom pour différents types de paramètres dans une classe. Après compilation, la méthode était "remplacée" par la dernière déclaration, toutes les autres versions étaient ignorées, et des bugs apparaissaient.

Avantages :

  • Style familier pour certains langages

Inconvénients :

  • Ne fonctionne pas complètement en TypeScript, erreurs de compilation
  • Risque accru de cas manqués

Cas positif

On a créé plusieurs signatures avec des paramètres de type union, puis dans la méthode, on a traité toutes les variantes via des gardiens de type. Le compilateur a immédiatement averti des problèmes de typage.

Avantages :

  • Contrôle stricte des types
  • Sécurité
  • Facilité de test

Inconvénients :

  • Nécessite plus de code pour vérifier les variantes