ProgrammazioneSviluppatore Fullstack

Descrivi la meccanica degli operatori Spread e Rest in TypeScript, come funzionano con la tipizzazione rigorosa e cosa tenere a mente quando si lavora con oggetti e array?

Supera i colloqui con l'assistente IA Hintsage

Risposta.

Storia della domanda:

Spread (...) e Rest (...) sono alcune delle più popolari moderne costruzioni sintattiche arrivate da ES6. In TypeScript, hanno acquisito una rigidità tipologica, quindi l'uso di Spread e Rest è diventato non solo comodo, ma anche sicuro, se si rispettano correttamente i vincoli di tipo.

Problema:

Le operazioni Spread e Rest diventano fonte di errori se non si tiene conto del tipo dei valori o si mescolano tipi incompatibili (ad esempio, unendo oggetti con proprietà incompatibili o array di tipi diversi).

Soluzione:

In TypeScript, Spread viene utilizzato per copiare o unire le proprietà degli oggetti e gli elementi degli array. Rest consente di raccogliere elementi "residui" in una funzione o array, mentre la tipizzazione rigida controlla casi incompatibili, prevenendo errori in fase di compilazione.

Esempio di codice:

// Spread con oggetti const base = { a: 1, b: 2 }; const extended = { ...base, c: 3 }; // extended: { a: number; b: number; c: number } // Rest nei parametri di funzione function sum(...args: number[]): number { return args.reduce((acc, val) => acc + val, 0); } // Spread negli array const arr = [1, 2, 3]; const newArr = [...arr, 4, 5];

Caratteristiche chiave:

  • Spread garantisce la copia delle proprietà/elementi con controllo di compatibilità dei tipi
  • Rest garantisce un tipo rigoroso per i parametri restanti
  • Errori di tipo durante la fusione errata vengono catturati già in fase di compilazione

Domande trabocchetto.

Qual è la differenza tra copiare un oggetto tramite Spread e assegnare per riferimento?

Spread crea un nuovo oggetto con una copia di tutte le proprietà enumerabili, ma se l'oggetto contiene oggetti annidati, essi vengono copiati per riferimento (shallow copy).

const base = { a: 1, nested: { x: 2 } }; const copy = { ...base }; copy.nested.x = 42; console.log(base.nested.x); // 42

È possibile copiare solo determinate proprietà tramite Spread?

No, Spread copia tutte le proprietà enumerabili dell'oggetto. Per selezionare singole proprietà si utilizza la destrutturazione:

const { a, ...rest } = { a: 1, b: 2, c: 3 }; // rest: { b: 2, c: 3 }

Cosa succede se si uniscono due oggetti con proprietà identiche tramite Spread? Come influisce sulla tipizzazione?

Le proprietà dell'ultimo oggetto sovrascriveranno quelle precedenti. Il tipo dell'ultima proprietà sarà considerato finale:

const a = { val: 1 }; const b = { val: 'hello' }; const merged = { ...a, ...b }; // merged: { val: string } (e non number)

Errori di tipo e anti-pattern

  • Usare Spread per clonare profondamente oggetti annidati, anche se questo è solo "shallow copy"
  • Tipizzazione errata dei parametri rest (specificare il tipo any[] invece di uno specifico)
  • Unire oggetti con tipi di proprietà incompatibili sovrapposti

Esempio dalla vita reale

Caso negativo

Nel progetto si è deciso di unire i parametri di configurazione tramite Spread. Uno degli oggetti aveva la proprietà timeout: number, l'altro timeout: string. Non sono stati notati errori fino al runtime, quando la funzione si è bloccata a causa di un tipo errato.

Pro:

  • Realizzato rapidamente in poche righe

Contro:

  • Gli errori di tipizzazione non sono visibili se viene specificato esplicitamente: any
  • Trappole nella sovrascrittura delle proprietà

Caso positivo

È stato utilizzato lo Spread tipizzato per unire interfacce rigorose e la destrutturazione per separare i campi non necessari. Il compilatore ha segnalato immediatamente gli errori.

Pro:

  • Controllo automatico e evidenziazione degli errori in caso di incompatibilità
  • Unione e modifica tipo in modo sicuro

Contro:

  • Richiede attenta progettazione delle interfacce