eslint/no-unused-vars 正确性
它的作用
禁止声明未在代码中使用的变量、导入或类型声明。
为什么这是不好的?
在代码中声明但未被任何地方使用过的变量,很可能是由于重构不完整导致的错误。这些变量会占用代码空间,并可能引起读者的困惑。
// `b` 未被使用;这表明存在一个错误。
function add(a: number, b: number) {
return a;
}
console.log(add(1, 2));如果满足以下任一条件,则认为变量 foo 是“已使用”的:
- 它被调用(
foo())或构造(new foo()) - 它被读取(
var bar = foo) - 它作为参数传递给函数或构造器(
doSomething(foo)) - 它在传递给另一个函数的函数内部被读取(
doSomething(function() { foo(); })) - 它被导出(
export const foo = 42) - 它被用作 TypeScript
typeof操作符的操作数(const bar: typeof foo = 4)
如果变量仅被声明(var foo = 5)或赋值(foo = 7),则不被认为是“已使用”。
类型
此规则对 TypeScript 类型、接口、枚举和命名空间具有完整支持。
类型或接口 Foo 被认为是“已使用”的,如果它以以下任意方式被使用:
- 在另一个类型或接口的定义中被使用
- 用作类型注解或函数签名的一部分
- 在类型断言或
satisfies表达式中被使用
如果一个类型或接口仅在其自身定义中被使用(例如 type Foo = Array<Foo>),则不被认为是“已使用”。
枚举和命名空间与变量、类、函数等处理方式相同。
被忽略的文件
此规则完全忽略 .d.ts、.astro、.svelte 和 .vue 文件。.d.ts 文件中声明的变量、类、接口和类型通常由其他文件使用,而这些文件不会被 Oxlint 检查。由于 Oxlint 不支持解析模板语法,因此该规则无法判断变量在 Vue / Svelte / Astro 文件中是否被使用或未被使用。
导出
原始 ESLint 规则通过 /* exported variableName */ 注释来识别变量在其他脚本中被使用,从而不应被视为未使用。但由于 ES 模块现在已成为 TC39 标准,Oxlint 不支持此功能。
示例
此规则的 错误 代码示例:
/* no-unused-vars: "error" */
/* 如果你在 .oxlintrc.json 中将 `some_unused_var` 定义为全局变量 */
// 它会检查你定义为全局的变量
some_unused_var = 42;
var x;
// 只写变量不被认为是已使用。
var y = 10;
y = 5;
// 对自身进行修改的读取不被认为是已使用。
var z = 0;
z = z + 1;
// 默认情况下,未使用的参数会引发警告。
(function (foo) {
return 5;
})();
// 未使用的递归函数也会引发警告。
function fact(n) {
if (n < 2) return 1;
return n * fact(n - 1);
}
// 当函数定义通过数组解构时,数组中的未使用项也会引发警告。
function getY([x, y]) {
return y;
}type A = Array<A>;
enum Color {
Red,
Green,
Blue,
}此规则的 正确 代码示例:
/* no-unused-vars: "error" */
var x = 10;
alert(x);
// foo 在此处被认为是已使用
myFunc(
function foo() {
// ...
}.bind(this),
);
(function (foo) {
return foo;
})();
var myFunc;
myFunc = setTimeout(function () {
// myFunc 被认为是已使用
myFunc();
}, 50);
// 解构数组中仅第二个参数被使用。
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);/* exported variableName */ 操作的 错误 代码示例:
/* exported global_var */
// 不再生效,应改用 ES 模块。
var global_var = 42;配置
此规则接受一个配置对象,包含以下属性:
args
type: "after-used" | "all" | "none"
default: "after-used"
控制如何检查未使用的参数。
"after-used"
在最后一个被使用的参数之前出现的未使用位置参数将不会被检查,但所有命名参数以及最后一个被使用参数之后的所有位置参数都将被检查。
"all"
所有命名参数都必须被使用。
"none"
不检查参数。
argsIgnorePattern
指定对未使用参数的例外情况。名称匹配此模式的参数将被忽略。
默认情况下,该模式为 ^_,除非使用对象配置选项。在这种情况下,其默认值为 [None]。请注意,此行为与 ESLint 及 TypeScript-ESLint 均不同,因为它们从不提供默认模式。
示例
当模式为 ^_ 时,此选项的 正确 代码示例:
function foo(_a, b) {
console.log(b);
}
foo(1, 2);caughtErrors
type: "all" | "none"
用于 catch 块验证。
"all"
所有命名参数都必须被使用。
"none"
不检查错误对象。
caughtErrorsIgnorePattern
指定对 catch 块内捕获错误的例外情况。名称匹配此模式的 catch 块中声明的变量将被忽略。
示例
当模式为 ^ignore 时,正确 的代码示例:
try {
// ...
} catch (ignoreErr) {
console.error("Error caught in catch block");
}destructuredArrayIgnorePattern
此选项指定在解构模式中不会被检查使用情况的例外。名称匹配此模式的数组解构中声明的变量将被忽略。
默认情况下,此模式未设置。
示例
当模式为 ^_ 时,此选项的 正确 代码示例:
const [a, _b, c] = ["a", "b", "c"];
console.log(a + c);
const {
x: [_a, foo],
} = bar;
console.log(foo);
let _m, n;
foo.forEach((item) => {
[_m, n] = item;
console.log(n);
});ignoreClassWithStaticInitBlock
type: boolean
default: false
ignoreClassWithStaticInitBlock 选项是一个布尔值。静态初始化块允许在类定义求值期间初始化静态变量并执行代码,意味着静态块代码在不创建类的新实例的情况下执行。当设为 true 时,此选项忽略包含静态初始化块的类。
示例
当配置为 { "ignoreClassWithStaticInitBlock": true } 时,错误 代码示例:
/* no-unused-vars: ["error", { "ignoreClassWithStaticInitBlock": true }]*/
class Foo {
static myProperty = "some string";
static mymethod() {
return "some string";
}
}
class Bar {
static {
let baz; // 未使用的变量
}
}当配置为 { "ignoreClassWithStaticInitBlock": true } 时,正确 代码示例:
/* no-unused-vars: ["error", { "ignoreClassWithStaticInitBlock": true }]*/
class Foo {
static {
let bar = "some string";
console.log(bar);
}
}ignoreRestSiblings
type: boolean
default: false
使用剩余属性可以“省略”对象中的某些属性,但默认情况下,同级属性会被标记为“未使用”。启用此选项后,剩余属性的同级属性将被忽略。
示例
当此选项设置为 true 时,正确 代码示例:
// 'foo' 和 'bar' 因具有剩余属性同级而被忽略。
var { foo, ...coords } = data;
var bar;
({ bar, ...coords } = data);ignoreUsingDeclarations
type: boolean
default: false
当设为 true 时,规则将忽略使用 using 或 await using 声明的变量,即使它们未被使用。
这在处理需要通过显式资源管理提案进行释放的资源时非常有用,此时主要目的是副作用的释放,而非使用资源本身。
示例
当配置为 { "ignoreUsingDeclarations": true } 时,正确 代码示例:
/* no-unused-vars: ["error", { "ignoreUsingDeclarations": true }]*/
using resource = getResource();
await using anotherResource = getAnotherResource();reportUsedIgnorePattern
type: boolean
default: false
reportUsedIgnorePattern 选项是一个布尔值。启用此选项后,如果变量匹配任何有效的忽略模式选项(varsIgnorePattern、argsIgnorePattern、caughtErrorsIgnorePattern 或 destructuredArrayIgnorePattern),即使它们已被使用,也会被报告。
示例
当配置为 { "reportUsedIgnorePattern": true } 时,错误 代码示例:
/* no-unused-vars: ["error", { "reportUsedIgnorePattern": true, "varsIgnorePattern": "[iI]gnored" }]*/
var firstVarIgnored = 1;
var secondVar = 2;
console.log(firstVarIgnored, secondVar);当配置为 { "reportUsedIgnorePattern": true } 时,正确 代码示例:
/* no-unused-vars: ["error", { "reportUsedIgnorePattern": true, "varsIgnorePattern": "[iI]gnored" }]*/
var firstVar = 1;
var secondVar = 2;
console.log(firstVar, secondVar);reportVarsOnlyUsedAsTypes
type: boolean
default: false
reportVarsOnlyUsedAsTypes 选项是一个布尔值。
如果为 true,规则还会报告仅用作类型的变量。
示例
当配置为 { "reportVarsOnlyUsedAsTypes": true } 时,错误 代码示例:
/* no-unused-vars: ["error", { "reportVarsOnlyUsedAsTypes": true }] */
const myNumber: number = 4;
export type MyNumber = typeof myNumber当配置为 { "reportVarsOnlyUsedAsTypes": true } 时,正确 代码示例:
export type MyNumber = number;注意:即使配置为 { "reportVarsOnlyUsedAsTypes": false },如果某个值仅在自身中作为类型使用,仍将被报告:
function foo(): typeof foo {}vars
type: "all" | "local"
default: "all"
控制如何检查全局作用域中变量的使用情况。
"all"
检查所有变量的使用情况,包括全局作用域中的变量。
"local"
仅检查局部声明的变量是否被使用,但允许全局变量未被使用。
varsIgnorePattern
指定对未使用变量的例外情况。名称匹配此模式的变量将被忽略。
默认情况下,该模式为 ^_,除非使用对象配置选项。在这种情况下,其默认值为 [None]。请注意,此行为与 ESLint 及 TypeScript-ESLint 均不同,因为它们从不提供默认模式。
示例
当模式为 ^_ 时,此选项的 正确 代码示例:
var _a = 10;
var b = 10;
console.log(b);如何使用
要通过配置文件或 CLI 启用 此规则,可以使用:
{
"rules": {
"no-unused-vars": "error"
}
}oxlint --deny no-unused-vars