For AI agents: the complete documentation index is available at https://rslint.rs/llms.txt, the full documentation bundle is available at https://rslint.rs/llms-full.txt, and this page is available as Markdown at https://rslint.rs/rules/unicorn/no-useless-length-check.md.
close

no-useless-length-check

Unreleased

Configuration

rslint.config.ts
import { defineConfig, unicornPlugin } from '@rslint/core';

export default defineConfig([
  unicornPlugin.configs.recommended,
  {
    rules: {
      'unicorn/no-useless-length-check': 'error',
    },
  },
]);

Rule Details

Disallows redundant array length checks next to Array#some(), Array#every(), or before a for…of loop over the same receiver. some() already returns false for an empty array, every() returns true, and for…of performs no iterations.

The rule checks .length === 0, .length !== 0, and .length > 0, using the literal spelling 0. Use it with unicorn/explicit-length-check to normalize other length checks. Known non-array receivers are ignored; typed arrays are supported. Only adjacent conditions in the same && or || chain match. Explicit TypeScript and JSDoc return annotations on local factories, including callable binding annotations, are respected when identifying a non-array receiver. A reassigned factory's original annotation is not used.

Examples of incorrect code:

const hasMatch = array.length > 0 && array.some(predicate);
const allMatch = array.length === 0 || array.every(predicate);

if (array.length !== 0) {
  for (const element of array) {
    use(element);
  }
}

Examples of correct code:

const hasMatch = array.some(predicate);
const allMatch = array.every(predicate);

for (const element of array) {
  use(element);
}

const nonEmptyAndAllMatch = array.length > 0 && array.every(predicate);
const emptyOrHasMatch = array.length === 0 || array.some(predicate);

A leading length check is automatically removed when evaluating the method arguments has no side effects. A trailing check is automatically removed only when the callback is an inline function without side effects. Other matching method checks offer an editor suggestion because removing the check can change which side effects run.

A guarded for…of loop is unwrapped when its indentation can be preserved. When necessary, a semicolon keeps the following statement outside the loop. Comments in the removed text and multiline tokens prevent automatic fixes. Loops with an else branch, multiple statements in the guarded block, or for await…of are ignored. A loop binding referenced by the iterable also prevents a report.

Options

This rule has no options.

Differences from upstream

rslint also recognizes known non-array results through a stable local factory alias. Given var factory = make; const array = factory(), it keeps array.length > 0 && array.some(Boolean) if make() explicitly returns an object. This also applies to a callable binding annotation such as make: () => {length: number; some: Function}. Unicorn v79.0.0 can remove the guard in these cases, even if the object's some() returns true when its length is zero.

Property reads in evaluated call arguments or callbacks offer suggestions because a getter can run user code or change the array's length. For example, array.some(value => value.ok) && array.length > 0 keeps its length guard until the suggestion is accepted. Unicorn v79.0.0 automatically removes this guard.

Destructuring in a callback can also invoke getters or iterators that change the array's length. For example, array.some(({ok}) => ok) && array.length > 0 offers a suggestion instead of Unicorn v79.0.0's automatic fix. The same applies to array destructuring and destructuring inside the callback body.

Computed property keys in evaluated arguments or callbacks offer suggestions unless the key has a known primitive value. For example, array.length > 0 && array.some(Boolean, {[key]: true}) keeps its guard because converting key to a property name can run user code even when array is empty. Unicorn v79.0.0 removes this check automatically.

For the following leading check, rslint offers an editor suggestion because evaluating the tagged template can run user code even when the array is empty. Unicorn v79.0.0 removes this check automatically.

array.length > 0 && array.some(tag`text`);

Applying the suggestion calls tag even when array is empty. Review whether that call is safe before accepting the suggestion.

Leading checks also offer suggestions when evaluating the method arguments performs a spread, including spreads nested inside arrays, objects, or JSX:

array.length > 0 && array.some(...callbacks);
array.length === 0 || array.every(predicate, { ...options });

Removing the guard can consume an iterator or invoke getters even when the array is empty. For leading checks, spreads inside an inline callback's body do not prevent an automatic fix because creating the callback does not run its body. For trailing checks, a callback that spreads JSX props offers a suggestion because a getter can change the array during iteration.

rslint also adds a semicolon when unwrapping a loop would attach the following statement to its body. A following [value].forEach(...), for example, stays outside the loop instead of becoming part of the loop body's last call.

Original Documentation