eslint/no-unused-vars Correctness ​
What it does ​
Disallows variable declarations, imports, or type declarations that are not used in code.
Why is this bad? ​
Variables that are declared and not used anywhere in the code are most likely an error due to incomplete refactoring. Such variables take up space in the code and can lead to confusion by readers.
// `b` is unused; this indicates a bug.
function add(a: number, b: number) {
return a;
}
console.log(add(1, 2));A variable foo is considered to be used if any of the following are true:
- It is called (
foo()) or constructed (new foo()) - It is read (
var bar = foo) - It is passed into a function or constructor as an argument (
doSomething(foo)) - It is read inside of a function that is passed to another function (
doSomething(function() { foo(); })) - It is exported (
export const foo = 42) - It is used as an operand to TypeScript's
typeofoperator (const bar: typeof foo = 4)
A variable is not considered to be used if it is only ever declared (var foo = 5) or assigned to (foo = 7).
Types ​
This rule has full support for TypeScript types, interfaces, enums, and namespaces.
A type or interface Foo is considered to be used if it is used in any of the following ways:
- It is used in the definition of another type or interface.
- It is used as a type annotation or as part of a function signature.
- It is used in a cast or
satisfiesexpression.
A type or interface is not considered to be used if it is only ever used in its own definition, e.g. type Foo = Array<Foo>.
Enums and namespaces are treated the same as variables, classes, functions, etc.
Ignored Files ​
This rule ignores .d.ts files and .vue files entirely. Variables, classes, interfaces, and types declared in .d.ts files are generally used by other files, which are not checked by Oxlint. Since Oxlint does not support parsing Vue templates, this rule cannot tell if a variable is used or unused in a Vue file.
Exported ​
The original ESLint rule recognizes /* exported variableName */ comments as a way to indicate that a variable is used in another script and should not be considered unused. Since ES6 modules are now a TC39 standard, Oxlint does not support this feature.
Examples ​
Examples of incorrect code for this rule:
/*eslint no-unused-vars: "error"*/
/*global some_unused_var*/
// It checks variables you have defined as global
some_unused_var = 42;
var x;
// Write-only variables are not considered as used.
var y = 10;
y = 5;
// A read for a modification of itself is not considered as used.
var z = 0;
z = z + 1;
// By default, unused arguments cause warnings.
(function(foo) {
return 5;
})();
// Unused recursive functions also cause warnings.
function fact(n) {
if (n < 2) return 1;
return n * fact(n - 1);
}
// When a function definition destructures an array, unused entries from
// the array also cause warnings.
function getY([x, y]) {
return y;
}type A = Array<A>;
enum Color {
Red,
Green,
Blue,
}Examples of correct code for this rule:
/*eslint no-unused-vars: "error"*/
var x = 10;
alert(x);
// foo is considered used here
myFunc(function foo() {
// ...
}.bind(this));
(function(foo) {
return foo;
})();
var myFunc;
myFunc = setTimeout(function() {
// myFunc is considered used
myFunc();
}, 50);
// Only the second argument from the destructured array is used.
function getY([, y]) {
return y;
}export const x = 1;
const y = 1;
export { y };
type A = Record<string, unknown>;
type B<T> = T extends Record<infer K, any> ? K : never;
const x = "foo" as B<A>;
console.log(x);Examples of incorrect code for /* exported variableName */ operation:
/* exported global_var */
// Not respected, use ES6 modules instead.
var global_var = 42;Configuration ​
This rule accepts a configuration object with the following properties:
args ​
Controls how unused arguments are checked.
This option has three settings:
after-used- Unused positional arguments that occur before the last used argument will not be checked, but all named arguments and all positional arguments after the last used argument will be checked. This is the default setting.all- All named arguments must be used.none- Do not check arguments.
caughtErrors ​
type: boolean
Used for catch block validation.
It has two settings:
none- do not check error objects. This is the default setting.all- all named arguments must be used.nonecorresponds tofalse, whileallcorresponds totrue`.
ignoreClassWithStaticInitBlock ​
type: boolean
The ignoreClassWithStaticInitBlock option is a boolean (default: false). Static initialization blocks allow you to initialize static variables and execute code during the evaluation of a class definition, meaning the static block code is executed without creating a new instance of the class. When set to true, this option ignores classes containing static initialization blocks.
Example ​
Examples of incorrect code for the { "ignoreClassWithStaticInitBlock": true } option
/*eslint no-unused-vars: ["error", { "ignoreClassWithStaticInitBlock": true }]*/
class Foo {
static myProperty = "some string";
static mymethod() {
return "some string";
}
}
class Bar {
static {
let baz; // unused variable
}
}Examples of correct code for the { "ignoreClassWithStaticInitBlock": true } option
/*eslint no-unused-vars: ["error", { "ignoreClassWithStaticInitBlock": true }]*/
class Foo {
static {
let bar = "some string";
console.log(bar);
}
}ignoreRestSiblings ​
type: boolean
Using a Rest property it is possible to "omit" properties from an object, but by default the sibling properties are marked as "unused". With this option enabled the rest property's siblings are ignored.
By default this option is false.
Example ​
Examples of correct code when this option is set to true:
// 'foo' and 'bar' were ignored because they have a rest property sibling.
var { foo, ...coords } = data;
var bar;
({ bar, ...coords } = data);ignoreUsingDeclarations ​
type: boolean
The ignoreUsingDeclarations option is a boolean (default: false). When set to true, the rule will ignore variables declared with using or await using declarations, even if they are unused.
This is useful when working with resources that need to be disposed via the explicit resource management proposal, where the primary purpose is the disposal side effect rather than using the resource.
Example ​
Examples of correct code for the { "ignoreUsingDeclarations": true } option:
/*eslint no-unused-vars: ["error", { "ignoreUsingDeclarations": true }]*/
using resource = getResource();
await using anotherResource = getAnotherResource();reportUsedIgnorePattern ​
type: boolean
The reportUsedIgnorePattern option is a boolean (default: false). Using this option will report variables that match any of the valid ignore pattern options (varsIgnorePattern, argsIgnorePattern, caughtErrorsIgnorePattern, or destructuredArrayIgnorePattern) if they have been used.
Example ​
Examples of incorrect code for the { "reportUsedIgnorePattern": true } option:
/*eslint no-unused-vars: ["error", { "reportUsedIgnorePattern": true, "varsIgnorePattern": "[iI]gnored" }]*/
var firstVarIgnored = 1;
var secondVar = 2;
console.log(firstVarIgnored, secondVar);Examples of correct code for the { "reportUsedIgnorePattern": true } option:
/*eslint no-unused-vars: ["error", { "reportUsedIgnorePattern": true, "varsIgnorePattern": "[iI]gnored" }]*/
var firstVar = 1;
var secondVar = 2;
console.log(firstVar, secondVar);reportVarsOnlyUsedAsTypes ​
type: boolean
The reportVarsOnlyUsedAsTypes option is a boolean (default: false).
If true, the rule will also report variables that are only used as types.
Examples ​
Examples of incorrect code for the { "reportVarsOnlyUsedAsTypes": true } option:
/* eslint no-unused-vars: ["error", { "reportVarsOnlyUsedAsTypes": true }] */
const myNumber: number = 4;
export type MyNumber = typeof myNumberExamples of correct code for the { "reportVarsOnlyUsedAsTypes": true } option:
export type MyNumber = number;Note: even with { "reportVarsOnlyUsedAsTypes": false }, cases where the value is only used a type within itself will still be reported:
function foo(): typeof foo {}vars ​
Controls how usage of a variable in the global scope is checked.
This option has two settings:
allchecks all variables for usage, including those in the global scope. This is the default setting.localchecks only that locally-declared variables are used but will allow global variables to be unused.
How to use ​
To enable this rule in the CLI or using the config file, you can use:
oxlint --deny no-unused-vars{
"rules": {
"no-unused-vars": "error"
}
}