Skip to content

Latest commit

 

History

History
111 lines (83 loc) · 3.11 KB

File metadata and controls

111 lines (83 loc) · 3.11 KB

prefer-continue

📝 Prefer early continues over whole-loop conditional wrapping.

💼🚫 This rule is enabled in the ✅ recommended config. This rule is disabled in the ☑️ unopinionated config.

🔧 This rule is automatically fixable by the --fix CLI option.

Avoid wrapping an entire loop body in a conditional. A continue guard often makes the main path clearer by skipping uninteresting iterations first.

This rule only reports when a block-bodied loop contains exactly one statement and that statement is an if statement without else. With the default maximumStatements option, it does not report nested if statements, loops that continue after the if, or non-block loop bodies.

It also does not report when the if body unconditionally exits the iteration (its last statement is return, break, continue, or throw), since an early continue would not flatten anything.

Examples

// ❌
for (const item of items) {
	if (item.isActive) {
		process(item);
		save(item);
	}
}

// ✅
for (const item of items) {
	if (!item.isActive) {
		continue;
	}

	process(item);
	save(item);
}
// ✅
for (const item of items) {
	if (item.isActive) {
		process(item);
	}
}
// ✅
for (const item of items) {
	if (item.isActive) {
		process(item);
		save(item);
	}

	finish(item);
}
// ✅
function findActive(items) {
	for (const item of items) {
		if (item.isActive) {
			process(item);
			return item;
		}
	}
}

Options

maximumStatements

Type: integer
Default: 1

Maximum number of statements allowed in a whole-loop conditional wrapper.

With the default, a single-statement wrapper is allowed:

for (const item of items) {
	if (item.isActive) {
		process(item);
	}
}

Set maximumStatements to 0 to report any non-empty whole-loop conditional wrapper:

'unicorn/prefer-continue': [
	'error',
	{
		maximumStatements: 0,
	},
]

Autofix is conservative. It skips wrappers with comments outside the condition or moved body, trailing wrapper comments, moved lexical names that are used in the condition, direct eval(...) with moved lexical declarations, direct function, class, TypeScript, using, or await using declarations, and multiline-sensitive strings, templates, or JSX. Multiline unbraced consequents are report-only.

Related Rules

unicorn/prefer-early-return applies the same guard-clause idea to functions.

unicorn/no-useless-continue removes continue statements that do not change control flow. This rule creates a continue guard that skips the rest of the loop body, so the two rules are complementary.

ESLint's no-continue enforces the opposite style. Do not enable both rules together.