diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 369d61ce484..4fde6a321a4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -15836,15 +15836,31 @@ namespace ts { } } else if (compilerOptions.noUnusedLocals) { - forEach(local.declarations, d => error(d.name || d, Diagnostics._0_is_declared_but_never_used, local.name)); + forEach(local.declarations, d => errorUnusedLocal(d.name || d, local.name)); } } } } } + function errorUnusedLocal(node: Node, name: string) { + if (isIdentifierThatStartsWithUnderScore(node)) { + const declaration = getRootDeclaration(node.parent); + if (declaration.kind === SyntaxKind.VariableDeclaration && + (declaration.parent.parent.kind === SyntaxKind.ForInStatement || + declaration.parent.parent.kind === SyntaxKind.ForOfStatement)) { + return; + } + } + error(node, Diagnostics._0_is_declared_but_never_used, name); + } + function parameterNameStartsWithUnderscore(parameter: ParameterDeclaration) { - return parameter.name && parameter.name.kind === SyntaxKind.Identifier && (parameter.name).text.charCodeAt(0) === CharacterCodes._; + return parameter.name && isIdentifierThatStartsWithUnderScore(parameter.name); + } + + function isIdentifierThatStartsWithUnderScore(node: Node) { + return node.kind === SyntaxKind.Identifier && (node).text.charCodeAt(0) === CharacterCodes._; } function checkUnusedClassMembers(node: ClassDeclaration | ClassExpression): void { diff --git a/tests/baselines/reference/unusedLocalsStartingWithUnderscore.errors.txt b/tests/baselines/reference/unusedLocalsStartingWithUnderscore.errors.txt new file mode 100644 index 00000000000..ae72b6fcdd3 --- /dev/null +++ b/tests/baselines/reference/unusedLocalsStartingWithUnderscore.errors.txt @@ -0,0 +1,18 @@ +tests/cases/compiler/unusedLocalsStartingWithUnderscore.ts(7,9): error TS6133: '_' is declared but never used. + + +==== tests/cases/compiler/unusedLocalsStartingWithUnderscore.ts (1 errors) ==== + + for (const _ of []) { } + + for (const _ in []) { } + + namespace M { + let _; + ~ +!!! error TS6133: '_' is declared but never used. + for (const _ of []) { } + + for (const _ in []) { } + } + \ No newline at end of file diff --git a/tests/baselines/reference/unusedLocalsStartingWithUnderscore.js b/tests/baselines/reference/unusedLocalsStartingWithUnderscore.js new file mode 100644 index 00000000000..cca16a97824 --- /dev/null +++ b/tests/baselines/reference/unusedLocalsStartingWithUnderscore.js @@ -0,0 +1,27 @@ +//// [unusedLocalsStartingWithUnderscore.ts] + +for (const _ of []) { } + +for (const _ in []) { } + +namespace M { + let _; + for (const _ of []) { } + + for (const _ in []) { } +} + + +//// [unusedLocalsStartingWithUnderscore.js] +for (var _i = 0, _a = []; _i < _a.length; _i++) { + var _ = _a[_i]; +} +for (var _ in []) { } +var M; +(function (M) { + var _; + for (var _i = 0, _a = []; _i < _a.length; _i++) { + var _1 = _a[_i]; + } + for (var _2 in []) { } +})(M || (M = {})); diff --git a/tests/cases/compiler/unusedLocalsStartingWithUnderscore.ts b/tests/cases/compiler/unusedLocalsStartingWithUnderscore.ts new file mode 100644 index 00000000000..4e6930a6282 --- /dev/null +++ b/tests/cases/compiler/unusedLocalsStartingWithUnderscore.ts @@ -0,0 +1,13 @@ +//@noUnusedLocals:true + +for (const _ of []) { } + +for (const _ in []) { } + +namespace M { + let _; + for (const _ of []) { } + + for (const _ in []) { } +} + \ No newline at end of file