Skip to content

Variables declared but never read are dead code. They add noise, mislead readers, and often indicate a logic error — the value was computed but never actually used. The check covers let/const/var bindings, function declarations, class declarations, catch-clause variables, and function parameters.

ts
// flagged: count is declared but never read
function summarise(items: Item[]) {
  const count = items.length;   // unused
  return items.map(i => i.name).join(", ");
}
ts
// fix: remove or use the binding
function summarise(items: Item[]) {
  return items.map(i => i.name).join(", ");
}
ts
// opt-out: prefix with _ to signal intentionally unused
function handler(_event: Event, context: Context) {
  return context.respond("ok");
}

The check skips: ESM imports (tree-shaker territory), type-only symbols (TypeAlias, Interface, Enum — deferred to the type-aware tier), rest-pattern bindings (...rest), and all module-scope (top-level) bindings (which may be exported without the export being visible to the AST-only pass). Use the _ prefix convention to opt out of flagging for positional parameters you cannot remove.

MIT License