Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork2.8k
feat(eslint-plugin): [no-misused-spread] add new rule#8509
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Changes fromall commits
75812fc
f18acb8
22a50e5
985795a
3ff215f
8e760e0
5f9fae6
990006f
49692d2
1f76659
c45038f
a12c9ff
9f07bc1
ab20e73
3ef5a45
b97a397
e02d7a9
26434c3
0921b80
b8d7e47
3f9d545
b133698
c449dba
bb3031f
99c67a0
ef12015
c3fa340
bc3bcf2
137c371
db72726
92140f2
8a5e2dc
d2fe874
0b0ac03
8a1a309
dc1411f
02d7fd3
e90385a
fc57f13
a95cd5f
094ae02
f9a1d18
e20e49b
acd146f
af82cbb
9ff1ba1
f4cf064
3dea4cd
235ca44
a808081
9405682
2d60b29
a678af7
283bbb7
804fab4
fc0e114
07b69b8
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
--- | ||
description: 'Disallow using the spread operator when it might cause unexpected behavior.' | ||
--- | ||
import Tabs from '@theme/Tabs'; | ||
import TabItem from '@theme/TabItem'; | ||
> 🛑 This file is source code, not the primary documentation location! 🛑 | ||
> | ||
> See **https://typescript-eslint.io/rules/no-misused-spread** for documentation. | ||
The [spread operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax) (`...`) is a JavaScript | ||
JoshuaKGoldberg marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
feature that can be misused in ways not always reported by TypeScript. This rule disallows using the spread operator on types where | ||
spreading can lead to unexpected behavior. | ||
This rule disallows the spread operator in the following cases: | ||
JoshuaKGoldberg marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
- Spreading a string into an array | ||
JoshuaKGoldberg marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
- Spreading a `Promise` into an object | ||
- Spreading a function without properties into an object | ||
- Spreading a class instance or declaration into an object | ||
- Spreading an iterable (`Map`, `Array`, etc.) into an object | ||
JoshuaKGoldberg marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
## Examples | ||
<Tabs> | ||
<TabItem value="❌ Incorrect"> | ||
```ts | ||
declare const userName: string; | ||
const chars = [...userName]; | ||
declare const arr: number[]; | ||
const arrSpread = { ...arr }; | ||
declare const set: Set<number>; | ||
const setSpread = { ...set }; | ||
declare const map: Map<string, number>; | ||
const mapSpread = { ...map }; | ||
declare function getObj(): { a: 1; b: 2 }; | ||
const getObjSpread = { ...getObj }; | ||
``` | ||
</TabItem> | ||
<TabItem value="✅ Correct"> | ||
```ts | ||
declare const userName: string; | ||
const chars = userName.split(''); | ||
declare const arr: number[]; | ||
const arrSpread = [...arr]; | ||
declare const set: Set<number>; | ||
const setSpread = [...set]; | ||
declare const map: Map<string, number>; | ||
const mapObject = Object.fromEntries(map); | ||
declare function getObj(): { a: 1; b: 2 }; | ||
const getObjSpread = { ...getObj() }; | ||
``` | ||
</TabItem> | ||
</Tabs> | ||
## Options | ||
### `allow` | ||
This option allows marking specific types as "safe" to be spread. It takes an | ||
array of type specifiers to consider safe. | ||
This option takes the shared [`TypeOrValueSpecifier` format](/packages/type-utils/type-or-value-specifier). | ||
Examples of a configuration for this option: | ||
```json | ||
"@typescript-eslint/no-misused-spread": [ | ||
"error", | ||
{ | ||
"allowForKnownSafeIterables": [ | ||
"SafeType", | ||
{ "from": "file", "name": "SafeString", "path": "src/safe-string.ts" }, | ||
{ "from": "lib", "name": "BrandedArray" }, | ||
{ "from": "package", "name": "ThisIsSafe", "package": "safe-lib" } | ||
] | ||
} | ||
] | ||
``` | ||
<Tabs> | ||
<TabItem value="❌ Incorrect"> | ||
```ts | ||
type UnsafeIterable = Iterable<number>; | ||
declare const iterable: UnsafeIterable; | ||
const spreadIterable = { ...iterable }; | ||
type UnsafeBrandedString = string & { __brand: 'unsafe' }; | ||
declare const brandedString: UnsafeBrandedString; | ||
const spreadBrandedString = { ...brandedString }; | ||
``` | ||
</TabItem> | ||
<TabItem value="✅ Correct"> | ||
```ts option='{"allow":["SafeIterable", "BrandedString"]}' | ||
type SafeIterable = Iterable<number>; | ||
declare const iterable: SafeIterable; | ||
const spreadIterable = { ...iterable }; | ||
type BrandedString = string & { __brand: 'safe' }; | ||
declare const brandedString: BrandedString; | ||
const spreadBrandedString = { ...brandedString }; | ||
``` | ||
</TabItem> | ||
</Tabs> | ||
## When Not To Use It | ||
If you intentionally want to use the spread operator in those cases, and expect | ||
the specific behavior that comes with it, you might not want this rule. | ||
For example, when you want to spread an array into an object and expect the | ||
result to be an object with the array elements as values and the array indices | ||
as keys. | ||
JoshuaKGoldberg marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
If your use cases for unusual spreads only involve a few types, you might consider using | ||
[ESLint disable comments](https://eslint.org/docs/latest/use/configure/rules#using-configuration-comments-1) | ||
and/or the [`allow` option](#allow) instead of completely disabling this rule. |
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.