Linter · Rules
@typescript-eslint/no-misused-spread
Disallow ... on values that do not spread the way they look
... in an object copies a value's own enumerable properties, and many values have none or the wrong ones. TypeScript accepts all of these:
| Spread | What you get |
|---|---|
A promise, a Map or a Set in an object | An empty object. |
| Another iterable in an object | Its own properties, not the values it yields. |
| An array in an object | The indexes as keys: { "0": .., "1": .. }. |
| A function without properties in an object | An empty object. You probably meant to call it. |
| A class instance in an object | The fields, without the class's methods and getters. |
| A class in an object | Only its static properties. |
| A string in an array or a call | Code points, which splits an emoji made of several of them. |
Configure
Off by default. This rule needs types, so turning it on makes bun lint type check your code first.
bunfig.toml
[lint.rules]
"@typescript-eslint/no-misused-spread" = "error" # or "warn"
Every option, set to its default:
bunfig.toml
[lint.rules]
"@typescript-eslint/no-misused-spread" = ["error", {
allow = [], # list of strings or objects
}]
Examples
Reported:
declare function loadUser(): Promise<{ name: string }>;
const roles = new Map([["admin", true]]);
const tags = ["new", "sale"];
const user = { ...loadUser() };
const access = { ...roles };
const labels = { ...tags };
Not reported:
declare function loadUser(): Promise<{ name: string }>;
const roles = new Map([["admin", true]]);
const tags = ["new", "sale"];
const user = { ...(await loadUser()) };
const access = Object.fromEntries(roles);
const labels = [...tags];
A class instance loses its methods:
class Cart {
items: string[] = [];
count() {
return this.items.length;
}
}
const copy = { ...new Cart() };
A string in an array:
function letters(name: string) {
return [...name];
}
Intl.Segmenter splits a string into the characters a reader sees:
function letters(name: string) {
return Array.from(new Intl.Segmenter().segment(name), part => part.segment);
}
Options
| Option | Default | What it does |
|---|---|---|
allow | [] | Types you can spread. Each is a name, or an object that also says where the type comes from: { "from": "file", "name": .. }, { "from": "lib", "name": .. } or { "from": "package", "name": .., "package": .. }. |
Not reported with allow: ["Cart"]:
class Cart {
items: string[] = [];
count() {
return this.items.length;
}
}
const copy = { ...new Cart() };