# @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. |

{/* Generated by src/codegen/lint-rule-docs.ts. Do not edit this section. */}

## Configure

Off by default. This rule needs types, so turning it on makes `bun lint` type check your code first.

```toml bunfig.toml
[lint.rules]
"@typescript-eslint/no-misused-spread" = "error" # or "warn"
```

Every option, set to its default:

```toml bunfig.toml
[lint.rules]
"@typescript-eslint/no-misused-spread" = ["error", {
  allow = [], # list of strings or objects
}]
```

{/* End of the generated section. */}

## Examples

Reported:

{/* bad {"count": 3} */}
```ts
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:

{/* good */}
```ts
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:

{/* bad */}
```ts
class Cart {
  items: string[] = [];
  count() {
    return this.items.length;
  }
}

const copy = { ...new Cart() };
```

A string in an array:

{/* bad */}
```ts
function letters(name: string) {
  return [...name];
}
```

`Intl.Segmenter` splits a string into the characters a reader sees:

{/* good */}
```ts
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"]`:

{/* good {"options": [{"allow": ["Cart"]}]} */}
```ts
class Cart {
  items: string[] = [];
  count() {
    return this.items.length;
  }
}

const copy = { ...new Cart() };
```
