Historique de la question:
Les opérateurs Spread (...) et Rest (...) sont parmi les constructions syntaxiques modernes les plus populaires, provenant de l'ES6. En TypeScript, ils acquièrent une stricte typologie, ce qui rend l'utilisation de Spread et Rest non seulement pratique, mais aussi sécurisée, si les limitations typologiques sont correctement respectées.
Problème:
Les opérations Spread et Rest deviennent sources d'erreurs si le type des valeurs n'est pas pris en compte ou si des types incompatibles sont mélangés (par exemple, fusionner des objets avec des propriétés incompatibles ou des tableaux de types différents).
Solution:
En TypeScript, Spread est utilisé pour copier ou combiner les propriétés des objets et les éléments des tableaux. Rest permet de regrouper les "éléments restants" dans une fonction ou un tableau, la typologie stricte vérifiant les cas incompatibles, empêchant ainsi les erreurs à l'étape de compilation.
Exemple de code :
// Spread avec des objets const base = { a: 1, b: 2 }; const extended = { ...base, c: 3 }; // extended: { a: number; b: number; c: number } // Rest dans les paramètres de la fonction function sum(...args: number[]): number { return args.reduce((acc, val) => acc + val, 0); } // Spread dans les tableaux const arr = [1, 2, 3]; const newArr = [...arr, 4, 5];
Caractéristiques clés :
Quelle est la différence entre la copie d'un objet via Spread et l'assignation par référence ?
Spread crée un nouvel objet avec une copie de toutes les propriétés énumérées, mais si l'objet contient des objets imbriqués, ils sont copiés par référence (shallow copy).
const base = { a: 1, nested: { x: 2 } }; const copy = { ...base }; copy.nested.x = 42; console.log(base.nested.x); // 42
Peut-on utiliser Spread pour copier uniquement certaines propriétés ?
Non, Spread copie toutes les propriétés énumérées de l'objet. Pour sélectionner certaines, on utilise la déstructuration :
const { a, ...rest } = { a: 1, b: 2, c: 3 }; // rest: { b: 2, c: 3 }
Que se passe-t-il si deux objets avec des propriétés identiques sont fusionnés via Spread ? Comment cela affecte-t-il la typologie ?
Les propriétés du dernier objet remplaceront les propriétés précédentes. Le type de la dernière propriété sera considéré comme final :
const a = { val: 1 }; const b = { val: 'hello' }; const merged = { ...a, ...b }; // merged: { val: string } (et non number)
Dans un projet, il a été décidé de fusionner les paramètres de configuration via Spread. L'un des objets avait la propriété timeout: number, l'autre — timeout: string. Aucun erreur n'a été remarquée jusqu'à l'exécution, lorsque la fonction a échoué en raison d'un type incorrect.
Avantages:
Inconvénients:
Utilisation d'un Spread typé pour fusionner des interfaces strictes, ainsi que déstructuration pour séparer les champs non souhaités. Les erreurs ont été immédiatement détectées par le compilateur.
Avantages:
Inconvénients: