Skip to content
NewBun 1.4.5 is out. Release notes
AphrodyBun

Linter · Rules

@typescript-eslint/no-unused-vars

Disallow variables, functions, parameters, imports, and types that are never used

A name that's declared and never read is dead code. It often points at a mistake, like a result you forgot to return, an import left behind after an edit, or a typo that turned one variable into two.

"Used" means read, so a variable that's only assigned to is reported. Exported names aren't. Unlike ESLint's no-unused-vars, this rule also checks types, interfaces, and enums, and it knows that options: Options uses Options.

To keep a name that you don't use, start it with _.

This rule is on by default in TypeScript files.

Configure

On by default as a warning. To turn it off:

bunfig.toml
[lint.rules]
"@typescript-eslint/no-unused-vars" = "off" # or "error"

Every option, set to its default:

bunfig.toml
[lint.rules]
"@typescript-eslint/no-unused-vars" = ["warn", {
  vars = "all", # "all" or "local"
  varsIgnorePattern = "^_",
  args = "after-used", # "all", "after-used" or "none"
  argsIgnorePattern = "^_",
  caughtErrors = "all", # "all" or "none"
  caughtErrorsIgnorePattern = "^_",
  destructuredArrayIgnorePattern = "^_",
  ignoreRestSiblings = true,
  ignoreClassWithStaticInitBlock = false,
  ignoreUsingDeclarations = false,
  reportUsedIgnorePattern = false,
  enableAutofixRemoval = { imports = false },
}]

Examples

Reported:

import { readFile } from "node:fs/promises";

interface Options {
  retries: number;
}

let attempts = 0;
attempts = attempts + 1;

function retry() {}

Not reported:

import { readFile } from "node:fs/promises";

interface Options {
  retries: number;
}

export async function load(path: string, options: Options) {
  let attempts = 0;
  while (attempts < options.retries) {
    attempts = attempts + 1;
  }
  return readFile(path);
}

A value that's only used in a type, through typeof, is reported. Nothing reads it when the code runs:

const defaults = { port: 3000 };

export type Settings = typeof defaults;

Options

An option you don't set keeps its default. With an ESLint config you get ESLint's defaults, which have no patterns and set ignoreRestSiblings to false.

OptionDefaultWhat it does
vars"all""local" skips variables in the global scope. The top level of a module isn't the global scope, so this only matters for scripts.
varsIgnorePattern"^_"Regular expression for variable names that can be unused.
args"after-used"Report unused parameters after the last one that's used. "all" reports every unused parameter, "none" reports none.
argsIgnorePattern"^_"Like varsIgnorePattern, for parameters.
caughtErrors"all""none" allows an unused error in catch (error).
caughtErrorsIgnorePattern"^_"Like varsIgnorePattern, for the catch parameter.
destructuredArrayIgnorePattern"^_"Like varsIgnorePattern, for names in const [a, b] = list.
ignoreRestSiblingstrueAllow unused names next to a ...rest in object destructuring.
ignoreClassWithStaticInitBlockfalseAllow an unused class that has a static {} block, which runs anyway.
ignoreUsingDeclarationsfalseAllow unused using and await using variables, which are disposed of anyway.
reportUsedIgnorePatternfalseReport a name that matches one of the patterns and is used.
enableAutofixRemoval{ "imports": false }With imports: true, --fix removes unused imports.

You can pass a string, "all" or "local", instead of the object. It sets vars.

By default, an unused parameter before a used one is allowed, because you can't remove it without moving the others:

export const doubled = [1, 2, 3].map((value, index) => index * 2);
export const doubled = [1, 2, 3].map((value, index) => index * 2);

A name that starts with _ is unused on purpose. That still applies when you set other options:

export function onMessage(_event: string) {}
export function onMessage(_event: string) {}
export function onMessage(_event: string) {}

ignoreRestSiblings is for taking properties out of an object:

export function publicFields(user: { name: string; password: string }) {
  const { password, ...rest } = user;
  return rest;
}
const _port = 3000;

export const url = `http://localhost:${_port}`;

With an oxlint config, the rule follows oxlint where the two differ:

  • Without an options object, variables and parameters that start with _ are ignored.
  • A value that's only used through typeof in a type counts as used, unless reportVarsOnlyUsedAsTypes is true.
  • fix replaces enableAutofixRemoval. It's { "imports": ..., "variables": ... }, and each is "off", "suggestion" (default), "fix", or "safe-fix".