no-object-spread-of-iterable

January 21, 2021 ยท View on GitHub

:mag: requires type information

Disallows spreading iterable types into an object.

Rationale

Spreading an iterable type like Array via object spread gives an object with the same numeric properties as the original array, but it no longer behaves like an array. There's no length property and all methods are not available. Unfortunately TypeScript cannot correctly represent that. So it tells you that object spread of an array gives you an array.

Most of the time this is a typo, as you need to use array spread to copy an array (square brackets instead of curly brackets): [...arr] instead of {...arr}.

Another possible mistake is a naive attempt to copy complex types like Map or Set via object spread. This gives you an empty object at runtime, but once again TypeScript doesn't warn you about that.

Examples

:thumbsdown: Examples of incorrect code

declare const arr: Array<number>;
declare const set: Set<number>;
declare const map: Map<number>;

console.log({...arr}.reverse()); // will throw at runtime, because 'reverse' does not exist on the resulting object
console.log({...set}); // this is not how you copy Set
console.log({...map}); // this is not how you copy Map

:thumbsup: Examples of correct code

declare const arr: Array<number>;
declare const set: Set<number>;
declare const map: Map<number>;

console.log([...arr].reverse()); // works as expected with square brackets
console.log(new Set(set)); // this is how you copy Set
console.log([...set]); // creates a new Array from the values in the Set
console.log(new Map(map)); // this is not how you copy Map
console.log([...map]); // creates a new Array with tuples representing the Map's entries

Further Reading