Skip to content

Commit

Permalink
Rule no-in-array
Browse files Browse the repository at this point in the history
  • Loading branch information
mahdi-farnia committed Oct 20, 2022
1 parent e95c87f commit 4e9da68
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 0 deletions.
37 changes: 37 additions & 0 deletions packages/eslint-plugin/docs/rules/no-in-array.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
description: 'Disallow using in operator for arrays.'
---

> 🛑 This file is source code, not the primary documentation location! 🛑
>
> See **https://typescript-eslint.io/rules/no-in-array** for documentation.
This rule bans using `in` operator for checking array members existence.

## Rule Details

Examples of code for this rule:

### ❌ Incorrect

```ts
const arr = ['a', 'b', 'c'];

if ('c' in arr) {
// ...
}
```

### ✅ Correct

```ts
const arr = ['a', 'b', 'c'];

if (arr.includes('a')) {
// ...
}
```

## When Not To Use It

When you want exactly iterate over array indexes.
1 change: 1 addition & 0 deletions packages/eslint-plugin/src/configs/all.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export = {
'@typescript-eslint/no-for-in-array': 'error',
'no-implied-eval': 'off',
'@typescript-eslint/no-implied-eval': 'error',
'@typescript-eslint/no-in-array': 'error',
'@typescript-eslint/no-inferrable-types': 'error',
'no-invalid-this': 'off',
'@typescript-eslint/no-invalid-this': 'error',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export = {
'@typescript-eslint/no-for-in-array': 'error',
'no-implied-eval': 'off',
'@typescript-eslint/no-implied-eval': 'error',
'@typescript-eslint/no-in-array': 'error',
'@typescript-eslint/no-misused-promises': 'error',
'@typescript-eslint/no-unnecessary-type-assertion': 'error',
'@typescript-eslint/no-unsafe-argument': 'error',
Expand Down
2 changes: 2 additions & 0 deletions packages/eslint-plugin/src/rules/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import noFloatingPromises from './no-floating-promises';
import noForInArray from './no-for-in-array';
import noImplicitAnyCatch from './no-implicit-any-catch';
import noImpliedEval from './no-implied-eval';
import noInArray from './no-in-array';
import noInferrableTypes from './no-inferrable-types';
import noInvalidThis from './no-invalid-this';
import noInvalidVoidType from './no-invalid-void-type';
Expand Down Expand Up @@ -179,6 +180,7 @@ export default {
'no-for-in-array': noForInArray,
'no-implicit-any-catch': noImplicitAnyCatch,
'no-implied-eval': noImpliedEval,
'no-in-array': noInArray,
'no-inferrable-types': noInferrableTypes,
'no-invalid-this': noInvalidThis,
'no-invalid-void-type': noInvalidVoidType,
Expand Down
46 changes: 46 additions & 0 deletions packages/eslint-plugin/src/rules/no-in-array.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import type { TSESTree } from '@typescript-eslint/utils';
import * as ts from 'typescript';

import * as util from '../util';

export default util.createRule<[], 'inArrayViolation'>({
name: 'no-in-array',
meta: {
docs: {
description: 'Disallow using in operator for arrays',
recommended: 'error',
requiresTypeChecking: true,
},
messages: {
inArrayViolation:
"'in' operator for arrays is forbidden. Use array.indexOf or array.includes instead.",
},
schema: [],
type: 'problem',
},
defaultOptions: [],
create(context) {
return {
"BinaryExpression[operator='in']"(node: TSESTree.BinaryExpression): void {
const parserServices = util.getParserServices(context);
const checker = parserServices.program.getTypeChecker();
const originalNode = parserServices.esTreeNodeToTSNodeMap.get(node);

const type = util.getConstrainedTypeAtLocation(
checker,
originalNode.right,
);

if (
util.isTypeArrayTypeOrUnionOfArrayTypes(type, checker) ||
(type.flags & ts.TypeFlags.StringLike) !== 0
) {
context.report({
node,
messageId: 'inArrayViolation',
});
}
},
};
},
});
40 changes: 40 additions & 0 deletions packages/eslint-plugin/tests/rules/no-in-array.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import rule from '../../src/rules/no-in-array';
import { getFixturesRootDir, RuleTester } from '../RuleTester';

const rootDir = getFixturesRootDir();
const ruleTester = new RuleTester({
parserOptions: {
ecmaVersion: 2015,
tsconfigRootDir: rootDir,
project: './tsconfig.json',
},
parser: '@typescript-eslint/parser',
});

ruleTester.run('no-in-array', rule, {
valid: [
{
code: `
if (x in {}) {
}
`,
},
],
invalid: [
{
code: `
if (x in ['z', 'y']) {
}
`,
errors: [{ messageId: 'inArrayViolation' }],
},
{
code: `
const arr = [5, 6, 7, 8];
const has_6 = 6 in arr;
`,
errors: [{ messageId: 'inArrayViolation' }],
},
],
});

0 comments on commit 4e9da68

Please sign in to comment.