no-labels

Disallow labeled statements

A label lets break and continue jump out of more than one loop at a time. Few people use labels, so readers have to stop and work out where the jump lands. Moving the loops into a function and using return does the same thing without a label.

The labeled statement is reported, and so is each break or continue that names a label.

Configure#

Off by default. To turn it on:

bunfig.toml
[lint.rules]
"no-labels" = "error" # or "warn"

Every option, set to its default:

bunfig.toml
[lint.rules]
"no-labels" = ["error", {
  allowLoop = false,
  allowSwitch = false,
}]

Examples#

example.js2 problems
let found;

search: for (const row of rows) {
  for (const cell of row.cells) {
    if (cell.value === target) {
      found = cell;
      break search;
    }
  }
}
example.jsNo problems
function findCell(rows, target) {
  for (const row of rows) {
    for (const cell of row.cells) {
      if (cell.value === target) return cell;
    }
  }
}

const found = findCell(rows, target);

Options#

OptionDefaultWhat it does
allowLoopfalseAllow labels on loops.
allowSwitchfalseAllow labels on switch statements.
example.jswith { "allowLoop": true }No problems
eachRow: for (const row of rows) {
  for (const cell of row.cells) {
    if (cell.isEmpty) continue eachRow;
  }
  print(row);
}
example.jswith { "allowSwitch": true }No problems
command: switch (input.type) {
  case "batch":
    for (const item of input.items) {
      if (item.stop) break command;
      run(item);
    }
    break;
}

A label on anything else, such as a block, is reported no matter what the options are:

example.jswith { "allowLoop": true, "allowSwitch": true }2 problems
setup: {
  if (!config) break setup;
  apply(config);
}