Skip to content
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add prefer-at rule #1331

Merged
merged 18 commits into from
Jun 3, 2021
2 changes: 1 addition & 1 deletion docs/rules/prefer-array-flat-map.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,4 @@ const foo = bar.flat().map(element => unicorn(element));

## Related rules

- [prefer-array-flat](./prefer-array-flat.md)
- [unicorn/prefer-array-flat](./prefer-array-flat.md)
2 changes: 1 addition & 1 deletion docs/rules/prefer-array-flat.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,4 @@ const foo = utils.flat(bar); // Fails

## Related rules

- [prefer-array-flat-map](./prefer-array-flat-map.md)
- [unicorn/prefer-array-flat-map](./prefer-array-flat-map.md)
122 changes: 122 additions & 0 deletions docs/rules/prefer-at.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# Prefer `.at()` method for index accessing
fisker marked this conversation as resolved.
Show resolved Hide resolved

Prefer [`Array#at()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/at), [`String#at()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/at), and `{TypedArray,NodeList,CSSRuleList,…}#at()` for index access.

This rule is fixable.

## Fail

```js
const foo = array[array.length - 1];
```

```js
const foo = array[array.length - 5];
```

```js
const foo = array.slice(-1)[0];
```

```js
const foo = array.slice(-1).pop();
```

```js
const foo = array.slice(-5).shift();
```

```js
const foo = string.charAt(string.length - 5);
```

```js
const foo = lodash.last(array);
```

## Pass

```js
const foo = array.at(-1);
```

```js
const foo = array.at(-5);
```

```js
const foo = array[100];
```

```js
// This rule is not checking this case, but `unicorn/prefer-negative-index` rule will fix it.
const foo = array.at(array.length - 1);
```

```js
array[array.length - 1] = foo;
```

## Options

Type: `object`

### checkAllIndexAccess

Type: `boolean`\
Default: `false`

This rule only check negative indexes by default, but you can also check positive indexes by setting `checkAllIndexAccess` to `true`.

Example:

```js
{
'unicorn/prefer-at': [
'error',
{
checkAllIndexAccess: true
}
]
}
```

```js
// eslint unicorn/prefer-at: ["error", {"checkAllIndexAccess": true}]
const foo = bar[10]; // Fails, will fix to `bar.at(10)`
const foo = bar[unknownProperty]; // Passes
const foo = string.chatAt(unknownIndex); // Fails
```

### getLastElementFunctions

Type: `string[]`

You can also check custom functions that get last element of objects.

`_.last()`, `lodash.last()`, and `underscore.last()` are checked by default.

Example:

```js
{
'unicorn/prefer-at': [
'error',
{
getLastElementFunctions: [
'getLast',
'utils.lastElement'
]
}
]
}
```

```js
// eslint unicorn/prefer-at: ["error", {"getLastElementFunctions": ["utils.lastElement"]}]
const foo = utils.lastElement(bar); // Fails
```

## Related rules

- [unicorn/prefer-negative-index](./prefer-negative-index.md)
4 changes: 4 additions & 0 deletions docs/rules/prefer-negative-index.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,7 @@ Array.prototype.slice.call(foo, -2, -1);
```js
Array.prototype.slice.apply(foo, [-2, -1]);
```

## Related rules

- [unicorn/prefer-at](./prefer-at.md)
2 changes: 2 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ module.exports = {
'unicorn/prefer-array-flat-map': 'error',
'unicorn/prefer-array-index-of': 'error',
'unicorn/prefer-array-some': 'error',
// TODO: Enable this by default when targeting Node.js support `Array#at`.
'unicorn/prefer-at': 'off',
'unicorn/prefer-date-now': 'error',
'unicorn/prefer-default-parameters': 'error',
'unicorn/prefer-dom-node-append': 'error',
Expand Down
2 changes: 2 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ Configure it in `package.json`.
"unicorn/prefer-array-flat-map": "error",
"unicorn/prefer-array-index-of": "error",
"unicorn/prefer-array-some": "error",
"unicorn/prefer-at": "off",
"unicorn/prefer-date-now": "error",
"unicorn/prefer-default-parameters": "error",
"unicorn/prefer-dom-node-append": "error",
Expand Down Expand Up @@ -183,6 +184,7 @@ Each rule has emojis denoting:
| [prefer-array-flat-map](docs/rules/prefer-array-flat-map.md) | Prefer `.flatMap(…)` over `.map(…).flat()`. | ✅ | 🔧 | |
| [prefer-array-index-of](docs/rules/prefer-array-index-of.md) | Prefer `Array#indexOf()` over `Array#findIndex()` when looking for the index of an item. | ✅ | 🔧 | 💡 |
| [prefer-array-some](docs/rules/prefer-array-some.md) | Prefer `.some(…)` over `.find(…)`. | ✅ | | 💡 |
| [prefer-at](docs/rules/prefer-at.md) | Prefer `.at()` method for index accessing. | | 🔧 | 💡 |
| [prefer-date-now](docs/rules/prefer-date-now.md) | Prefer `Date.now()` to get the number of milliseconds since the Unix Epoch. | ✅ | 🔧 | |
| [prefer-default-parameters](docs/rules/prefer-default-parameters.md) | Prefer default parameters over reassignment. | ✅ | 🔧 | 💡 |
| [prefer-dom-node-append](docs/rules/prefer-dom-node-append.md) | Prefer `Node#append()` over `Node#appendChild()`. | ✅ | 🔧 | |
Expand Down
8 changes: 3 additions & 5 deletions rules/consistent-destructuring.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict';
const avoidCapture = require('./utils/avoid-capture');
const getDocumentationUrl = require('./utils/get-documentation-url');
const {not} = require('./selectors');
const {not, notLeftHandSideSelector} = require('./selectors');

const MESSAGE_ID = 'consistentDestructuring';
const MESSAGE_ID_SUGGEST = 'consistentDestructuringSuggest';
Expand All @@ -16,12 +16,10 @@ const declaratorSelector = [
const memberSelector = [
'MemberExpression',
'[computed!=true]',
notLeftHandSideSelector(),
not([
'AssignmentExpression > .left',
'CallExpression > .callee',
'NewExpression > .callee',
'UpdateExpression > .argument',
'UnaryExpression[operator="delete"] > .argument'
'NewExpression> .callee'
])
].join('');

Expand Down
Loading