diff --git a/packages/eslint-plugin/src/rules/no-unused-vars.ts b/packages/eslint-plugin/src/rules/no-unused-vars.ts index f2bfa26bb1a8..4fed6a28de82 100644 --- a/packages/eslint-plugin/src/rules/no-unused-vars.ts +++ b/packages/eslint-plugin/src/rules/no-unused-vars.ts @@ -35,6 +35,7 @@ export type Options = [ destructuredArrayIgnorePattern?: string; ignoreClassWithStaticInitBlock?: boolean; ignoreRestSiblings?: boolean; + ignoreUsingDeclarations?: boolean; reportUsedIgnorePattern?: boolean; vars?: 'all' | 'local'; varsIgnorePattern?: string; @@ -49,6 +50,7 @@ interface TranslatedOptions { destructuredArrayIgnorePattern?: RegExp; ignoreClassWithStaticInitBlock: boolean; ignoreRestSiblings: boolean; + ignoreUsingDeclarations: boolean; reportUsedIgnorePattern: boolean; vars: 'all' | 'local'; varsIgnorePattern?: RegExp; @@ -127,6 +129,11 @@ export default createRule({ description: 'Whether to ignore sibling properties in `...` destructurings.', }, + ignoreUsingDeclarations: { + type: 'boolean', + description: + 'Whether to ignore using or await using declarations.', + }, reportUsedIgnorePattern: { type: 'boolean', description: @@ -162,6 +169,7 @@ export default createRule({ caughtErrors: 'all', ignoreClassWithStaticInitBlock: false, ignoreRestSiblings: false, + ignoreUsingDeclarations: false, reportUsedIgnorePattern: false, vars: 'all', }; @@ -173,6 +181,9 @@ export default createRule({ options.args = firstOption.args ?? options.args; options.ignoreRestSiblings = firstOption.ignoreRestSiblings ?? options.ignoreRestSiblings; + options.ignoreUsingDeclarations = + firstOption.ignoreUsingDeclarations ?? + options.ignoreUsingDeclarations; options.caughtErrors = firstOption.caughtErrors ?? options.caughtErrors; options.ignoreClassWithStaticInitBlock = firstOption.ignoreClassWithStaticInitBlock ?? @@ -548,6 +559,14 @@ export default createRule({ continue; } + if ( + def.type === TSESLint.Scope.DefinitionType.Variable && + options.ignoreUsingDeclarations && + (def.parent.kind === 'await using' || def.parent.kind === 'using') + ) { + continue; + } + if (hasRestSpreadSibling(variable)) { continue; } diff --git a/packages/eslint-plugin/tests/rules/no-unused-vars/no-unused-vars.test.ts b/packages/eslint-plugin/tests/rules/no-unused-vars/no-unused-vars.test.ts index 5f40bbcdc3cc..75dbb87439a7 100644 --- a/packages/eslint-plugin/tests/rules/no-unused-vars/no-unused-vars.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unused-vars/no-unused-vars.test.ts @@ -1715,6 +1715,48 @@ export {}; ], filename: 'foo.d.ts', }, + { + code: ` +using resource = getResource(); + `, + errors: [ + { + data: { + action: 'assigned a value', + additional: '', + varName: 'resource', + }, + line: 2, + messageId: 'unusedVar', + }, + ], + languageOptions: { + parserOptions: { + ecmaVersion: 2026, + }, + }, + }, + { + code: ` +await using resource = getResource(); + `, + errors: [ + { + data: { + action: 'assigned a value', + additional: '', + varName: 'resource', + }, + line: 2, + messageId: 'unusedVar', + }, + ], + languageOptions: { + parserOptions: { + ecmaVersion: 2026, + }, + }, + }, ], valid: [ @@ -3018,5 +3060,38 @@ declare class Bar {} `, filename: 'foo.d.ts', }, + { + code: ` +using resource = getResource(); +resource; + `, + languageOptions: { + parserOptions: { + ecmaVersion: 2026, + }, + }, + }, + { + code: ` +using resource = getResource(); + `, + languageOptions: { + parserOptions: { + ecmaVersion: 2026, + }, + }, + options: [{ ignoreUsingDeclarations: true }], + }, + { + code: ` +await using resource = getResource(); + `, + languageOptions: { + parserOptions: { + ecmaVersion: 2026, + }, + }, + options: [{ ignoreUsingDeclarations: true }], + }, ], }); diff --git a/packages/eslint-plugin/tests/schema-snapshots/no-unused-vars.shot b/packages/eslint-plugin/tests/schema-snapshots/no-unused-vars.shot index 0d9872aa6a11..e4919667312a 100644 --- a/packages/eslint-plugin/tests/schema-snapshots/no-unused-vars.shot +++ b/packages/eslint-plugin/tests/schema-snapshots/no-unused-vars.shot @@ -41,6 +41,10 @@ "description": "Whether to ignore sibling properties in `...` destructurings.", "type": "boolean" }, + "ignoreUsingDeclarations": { + "description": "Whether to ignore using or await using declarations.", + "type": "boolean" + }, "reportUsedIgnorePattern": { "description": "Whether to report variables that match any of the valid ignore pattern options if they have been used.", "type": "boolean" @@ -89,6 +93,8 @@ type Options = [ ignoreClassWithStaticInitBlock?: boolean; /** Whether to ignore sibling properties in `...` destructurings. */ ignoreRestSiblings?: boolean; + /** Whether to ignore using or await using declarations. */ + ignoreUsingDeclarations?: boolean; /** Whether to report variables that match any of the valid ignore pattern options if they have been used. */ reportUsedIgnorePattern?: boolean; /** Whether to check all variables or only locally-declared variables. */