ProgrammazioneSviluppatore Backend

Come implementare il sovraccarico dei metodi nelle classi TypeScript, quali errori evitare nella scrittura di metodi sovraccaricati e quali sottigliezze della tipizzazione possono sorgere?

Supera i colloqui con l'assistente IA Hintsage

Risposta.

Storia della domanda:

TypeScript supporta il sovraccarico dei metodi, analogamente ad altri linguaggi a tipizzazione rigorosa (ad esempio, Java o C#), tuttavia la sintassi del sovraccarico in TypeScript è concettualmente diversa. Qui è consentita più di una firma, ma solo un'implementazione. Questo può portare a confusione per gli sviluppatori familiari con il sovraccarico classico.

Problema:

Un errore comune è cercare di definire più metodi con insiemi di parametri diversi. Di conseguenza, si verifica un errore di compilazione, poiché TypeScript richiede un'unica implementazione che realizza tutte le varianti delle firme.

Soluzione:

Il sovraccarico si ottiene dichiarando più firme di un metodo e quindi un'implementazione che corrisponde a tutte le varianti. Per una corretta distinzione dei parametri, di solito si applicano type guard o instanceof.

Esempio di codice:

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}`); } }

Caratteristiche chiave:

  • Solo un'implementazione del metodo, ma più dichiarazioni-sigle
  • Deve garantire la gestione di tutte le varianti dei parametri di ingresso all'interno dell'implementazione
  • I tipi nell'implementazione devono essere il più ampi possibile

Domande insidiose.

È possibile implementare due implementazioni di un metodo con set di parametri diversi?

No. In TypeScript è consentita solo un'implementazione. Più metodi con lo stesso nome sono un errore sintattico.

Come tipizzare i parametri rest nel sovraccarico dei metodi per non perdere la tipizzazione rigorosa?

Si consiglia di descrivere i parametri esatti nelle firme e di utilizzare quelli il più generali possibile nell'implementazione:

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

Cosa succede se il tipo restituito dalle firme sovraccaricate è diverso?

TypeScript richiederà che l'implementazione restituisca un tipo unito (Union). In caso contrario, errore di compilazione.

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

Errori tipici e anti-pattern

  • Non conformità dell'implementazione alle firme di sovraccarico
  • Più implementazioni separate dello stesso metodo
  • Ignorare il controllo dei tipi dei parametri di ingresso nel corpo del metodo

Esempio dalla vita reale

Casi negativi

Nel prodotto si è tentato di implementare due metodi con lo stesso nome per diversi tipi di parametri nella classe. Dopo la compilazione il metodo "sostituiva" l'ultima dichiarazione, tutte le altre versioni venivano ignorate e si generavano bug.

Vantaggi:

  • Stile familiare per alcuni linguaggi

Svantaggi:

  • In TypeScript non funziona pienamente, errori durante la compilazione
  • Maggiore rischio di casi trascurati

Casi positivi

Sono state create più firme con parametri di tipo unito, e nel metodo sono state gestite tutte le varianti tramite type guard. Il compilatore ha immediatamente avvisato dei problemi di tipo.

Vantaggi:

  • Controllo rigoroso dei tipi
  • Sicurezza
  • Facilità di test

Svantaggi:

  • Richiede più codice per il controllo delle varianti