Historia de la pregunta:
Spread (...) y Rest (...) son algunas de las construcciones sintácticas modernas más populares que provienen de ES6. En TypeScript han adquirido estrictitud tipológica, por lo que el uso de Spread y Rest no solo se ha vuelto conveniente, sino también seguro, si se cumplen correctamente las restricciones de tipos.
Problema:
Las operaciones de Spread y Rest se convierten en fuentes de errores si no se tiene en cuenta el tipo de valores o si se mezclan tipos incompatibles (por ejemplo, se combinan objetos con propiedades incompatibles o arreglos de diferentes tipos).
Solución:
En TypeScript, Spread se utiliza para copiar o combinar propiedades de objetos y elementos de arreglos. Rest permite recoger elementos "restantes" en una función o arreglo, mientras que el tipado estricto verifica casos incompatibles, evitando errores en la etapa de compilación.
Ejemplo de código:
// Spread con objetos const base = { a: 1, b: 2 }; const extended = { ...base, c: 3 }; // extended: { a: number; b: number; c: number } // Rest en los parámetros de la función function sum(...args: number[]): number { return args.reduce((acc, val) => acc + val, 0); } // Spread en arreglos const arr = [1, 2, 3]; const newArr = [...arr, 4, 5];
Características clave:
¿En qué se diferencia la copia de un objeto a través de Spread de la asignación por referencia?
Spread crea un nuevo objeto con una copia de todas las propiedades enumerables, pero si el objeto tiene objetos anidados, se copian por referencia (copia superficial).
const base = { a: 1, nested: { x: 2 } }; const copy = { ...base }; copy.nested.x = 42; console.log(base.nested.x); // 42
¿Se puede usar Spread para copiar solo ciertas propiedades?
No, Spread copia todas las propiedades enumerables del objeto. Para seleccionar elementos específicos se utiliza la desestructuración:
const { a, ...rest } = { a: 1, b: 2, c: 3 }; // rest: { b: 2, c: 3 }
¿Qué ocurrirá si se combinan mediante Spread dos objetos con propiedades idénticas? ¿Cómo afecta esto al tipado?
Las propiedades del último objeto sobrescribirán las propiedades anteriores. En este caso, el tipo de la última propiedad se considerará final:
const a = { val: 1 }; const b = { val: 'hello' }; const merged = { ...a, ...b }; // merged: { val: string } (y no number)
En el proyecto decidieron combinar parámetros de configuración a través de Spread. Uno de los objetos tenía la propiedad timeout: number, y el otro — timeout: string. Sin embargo, no se detectaron errores hasta tiempo de ejecución, cuando la función falló debido a un tipo incorrecto.
Ventajas:
Desventajas:
Usaron Spread tipificado para combinar interfaces estrictas, así como desestructuración para separar campos innecesarios. El compilador detectó errores de inmediato.
Ventajas:
Desventajas: