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:
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)
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:
Contro:
È 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:
Contro: