@typescript-eslint/no-unused-vars
Disallow variables, functions, parameters, imports, and types that are never used
Also called typescript-eslint/no-unused-vars, typescript/no-unused-vars
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:
[lint.rules]
"@typescript-eslint/no-unused-vars" = "off" # or "error"Every option, set to its default:
[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#
import { readFilereadFile is defined but never used. } from "node:fs/promises";
interface OptionsOptions is defined but never used. {
retries: number;
}
let attempts = 0;
attemptsattempts is assigned a value but never used. = attempts + 1;
function retryretry is defined but never used.() {}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 defaultsdefaults is assigned a value but only used as a type. = { 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.
| Option | Default | What 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. |
ignoreRestSiblings | true | Allow unused names next to a ...rest in object destructuring. |
ignoreClassWithStaticInitBlock | false | Allow an unused class that has a static {} block, which runs anyway. |
ignoreUsingDeclarations | false | Allow unused using and await using variables, which are disposed of anyway. |
reportUsedIgnorePattern | false | Report 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);{ "args": "all" }1 problemexport const doubled = [1, 2, 3].map((valuevalue is defined but never used., 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) {}{ "args": "all" }No problemsexport function onMessage(_event: string) {}{ "argsIgnorePattern": "^unused" }1 problemexport function onMessage(_event_event is defined but never used. Allowed unused args must match /^unused/u.: string) {}ignoreRestSiblings is for taking properties out of an object:
export function publicFields(user: { name: string; password: string }) {
const { password, ...rest } = user;
return rest;
}{ "varsIgnorePattern": "^_", "reportUsedIgnorePattern": true }1 problemconst _port_port is marked as ignored but is used. Used vars must not match /^_/u. = 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
typeofin a type counts as used, unlessreportVarsOnlyUsedAsTypesistrue. fixreplacesenableAutofixRemoval. It's{ "imports": ..., "variables": ... }, and each is"off","suggestion"(default),"fix", or"safe-fix".