no-misused-spread
Disallow using the spread operator when it might cause unexpected behavior.
Extending "plugin:@typescript-eslint/strict-type-checked"
in an ESLint configuration enables this rule.
This rule requires type information to run.
Spread syntax (...
) is a JavaScript feature for creating an object with the joined properties of one or more other objects.
TypeScript allows spreading objects whose properties are not typically meant to be enumerated, such as arrays and class instances.
This rule disallows using the spread syntax on values whose types indicate doing so may cause unexpected behavior. That includes the following cases:
- Spreading a
Promise
into an object. You probably meant toawait
it. - Spreading a function without properties into an object. You probably meant to call it.
- Spreading an iterable (
Array
,Map
, etc.) into an object. Iterable objects usually do not have meaningful enumerable properties and you probably meant to spread it into an array instead. - Spreading a string into an array. String enumeration behaviors in JavaScript around encoded characters are often surprising.
- Spreading a
class
into an object. This copies all static own properties of the class, but none of the inheritance chain. - Spreading a class instance into an object. This does not faithfully copy the instance because only its own properties are copied, but the inheritance chain is lost, including all its methods.
- Flat Config
- Legacy Config
export default tseslint.config({
rules: {
"@typescript-eslint/no-misused-spread": "error"
}
});
module.exports = {
"rules": {
"@typescript-eslint/no-misused-spread": "error"
}
};
Try this rule in the playground ↗
Examples
- ❌ Incorrect
- ✅ Correct
declare const promise: Promise<number>;
const spreadPromise = { ...promise };
declare function getObject(): Record<string, strings>;
const getObjectSpread = { ...getObject };
declare const map: Map<string, number>;
const mapSpread = { ...map };
declare const userName: string;
const characters = [...userName];
Open in Playgrounddeclare class Box {
value: number;
}
const boxSpread = { ...Box };
declare const instance: Box;
const instanceSpread = { ...box };
Open in Playgrounddeclare const promise: Promise<number>;
const spreadPromise = { ...(await promise) };
declare function getObject(): Record<string, strings>;
const getObjectSpread = { ...getObject() };
declare const map: Map<string, number>;
const mapObject = Object.fromEntries(map);
declare const userName: string;
const characters = userName.split('');
Open in PlaygroundOptions
This rule accepts the following options:
type Options = [
{
/** An array of type specifiers that are known to be safe to spread. */
allow?: (
| {
from: 'file';
name: [string, ...string[]] | string;
path?: string;
}
| {
from: 'lib';
name: [string, ...string[]] | string;
}
| {
from: 'package';
name: [string, ...string[]] | string;
package: string;
}
| string
)[];
},
];
const defaultOptions: Options = [{ allow: [] }];
allow
An array of type specifiers that are known to be safe to spread. Default: []
.
This option takes the shared TypeOrValueSpecifier
format.
Examples of a configuration for this option in a file.ts
file:
"@typescript-eslint/no-misused-spread": [
"error",
{
"allow": [
{ "from": "file", "name": "BrandedString", "path": "file.ts" },
]
}
]
- ❌ Incorrect
- ✅ Correct
declare const unbrandedString: string;
const spreadUnbrandedString = [...unbrandedString];
Open in Playgroundtype BrandedString = string & { __brand: 'safe' };
declare const brandedString: BrandedString;
const spreadBrandedString = [...brandedString];
Open in PlaygroundWhen Not To Use It
If your application intentionally works with raw data in unusual ways, such as directly manipulating class prototype chains, you might not want this rule.
If your use cases for unusual spreads only involve a few types, you might consider using ESLint disable comments and/or the allow
option instead of completely disabling this rule.
Further Reading
Type checked lint rules are more powerful than traditional lint rules, but also require configuring type checked linting.
See Troubleshooting > Linting with Type Information > Performance if you experience performance degradations after enabling type checked rules.