Skip to main content

prefer-ts-extras-array-includes

Prefer arrayIncludes from ts-extras over array.includes(...).

arrayIncludes(...) improves inference and narrowing when checking whether unknown values belong to a known tuple/array.

Targeted pattern scopeโ€‹

This rule focuses on direct array.includes(value) calls that can be migrated to arrayIncludes(array, value) with deterministic fixes.

  • array.includes(value) call sites that can use arrayIncludes(array, value).

Alias indirection, wrapper helpers, and non-canonical call shapes are excluded to keep arrayIncludes(array, value) migrations safe.

What this rule reportsโ€‹

This rule reports array.includes(value) call sites when arrayIncludes(array, value) is the intended replacement.

  • array.includes(value) call sites that can use arrayIncludes(array, value).

Why this rule existsโ€‹

arrayIncludes is especially useful when checking if an unknown value belongs to a known literal tuple.

  • Membership checks can narrow candidate values in control flow.
  • Guard logic is consistent with other ts-extras predicates.
  • Native .includes call sites that need manual casts are reduced.

โŒ Incorrectโ€‹

const hasStatus = statuses.includes(inputStatus);

โœ… Correctโ€‹

const hasStatus = arrayIncludes(statuses, inputStatus);

Behavior and migration notesโ€‹

  • Runtime semantics follow native Array.prototype.includes.
  • Comparison uses SameValueZero (NaN matches NaN, +0 equals -0).
  • Return type remains boolean, with improved narrowing behavior when array values are literal unions.

Additional examplesโ€‹

โŒ Incorrect โ€” Additional exampleโ€‹

if (roles.includes(candidate)) {
grantAccess(candidate);
}

โœ… Correct โ€” Additional exampleโ€‹

if (arrayIncludes(roles, candidate)) {
grantAccess(candidate);
}

โœ… Correct โ€” Repository-wide usageโ€‹

const isKnownStatus = arrayIncludes(statuses, value);

ESLint flat config exampleโ€‹

import typefest from "eslint-plugin-typefest";

export default [
{
plugins: { typefest },
rules: {
"typefest/prefer-ts-extras-array-includes": "error",
},
},
];

When not to use itโ€‹

Disable this rule if your codebase intentionally standardizes on native .includes().

Package documentationโ€‹

ts-extras package documentation:

Source file: source/array-includes.ts

/**
A strongly-typed version of `Array#includes()` that properly acts as a type guard.

When `arrayIncludes` returns `true`, the type is narrowed to the array's element type.
When it returns `false`, the type remains unchanged (i.e., `unknown` stays `unknown`).

It was [rejected](https://github.com/microsoft/TypeScript/issues/26255#issuecomment-748211891) from being done in TypeScript itself.

@example
```
import {arrayIncludes} from 'ts-extras';

const values = ['a', 'b', 'c'] as const;
const valueToCheck: unknown = 'a';

if (arrayIncludes(values, valueToCheck)) {
// We now know that the value is of type `typeof values[number]`.
} else {
// The value remains `unknown`.
}
```

@category Improved builtin
@category Type guard
*/

Rule catalog ID: R007

Further readingโ€‹

Adoption resourcesโ€‹