mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 16:38:05 -06:00
fix(33054): allow variables starting with an underscore in for/of statement (#36739)
This commit is contained in:
parent
96f01227d4
commit
d8170faee1
@ -31013,6 +31013,18 @@ namespace ts {
|
||||
return tryCast(getRootDeclaration(node), isParameter);
|
||||
}
|
||||
|
||||
function isValidUnusedLocalDeclaration(declaration: Declaration): boolean {
|
||||
if (isBindingElement(declaration) && isIdentifierThatStartsWithUnderscore(declaration.name)) {
|
||||
return !!findAncestor(declaration.parent, ancestor =>
|
||||
isArrayBindingPattern(ancestor) || isVariableDeclaration(ancestor) || isVariableDeclarationList(ancestor) ? false :
|
||||
isForOfStatement(ancestor) ? true : "quit"
|
||||
);
|
||||
}
|
||||
|
||||
return isAmbientModule(declaration) ||
|
||||
(isVariableDeclaration(declaration) && isForInOrOfStatement(declaration.parent.parent) || isImportedDeclaration(declaration)) && isIdentifierThatStartsWithUnderscore(declaration.name!);
|
||||
}
|
||||
|
||||
function checkUnusedLocalsAndParameters(nodeWithLocals: Node, addDiagnostic: AddUnusedDiagnostic): void {
|
||||
// Ideally we could use the ImportClause directly as a key, but must wait until we have full ES6 maps. So must store key along with value.
|
||||
const unusedImports = createMap<[ImportClause, ImportedDeclaration[]]>();
|
||||
@ -31026,8 +31038,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
for (const declaration of local.declarations) {
|
||||
if (isAmbientModule(declaration) ||
|
||||
(isVariableDeclaration(declaration) && isForInOrOfStatement(declaration.parent.parent) || isImportedDeclaration(declaration)) && isIdentifierThatStartsWithUnderscore(declaration.name!)) {
|
||||
if (isValidUnusedLocalDeclaration(declaration)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
//// [unusedVariablesWithUnderscoreInForOfLoop.ts]
|
||||
function f() {
|
||||
for (const [_a, b] of [['key', 1]]) {
|
||||
console.log(b);
|
||||
}
|
||||
|
||||
for (const [a, _b] of [['key', 1]]) {
|
||||
console.log(a);
|
||||
}
|
||||
|
||||
for (const [_a, _b] of [['key', 1]]) {}
|
||||
}
|
||||
|
||||
|
||||
//// [unusedVariablesWithUnderscoreInForOfLoop.js]
|
||||
function f() {
|
||||
for (var _i = 0, _c = [['key', 1]]; _i < _c.length; _i++) {
|
||||
var _d = _c[_i], _a = _d[0], b = _d[1];
|
||||
console.log(b);
|
||||
}
|
||||
for (var _e = 0, _f = [['key', 1]]; _e < _f.length; _e++) {
|
||||
var _g = _f[_e], a = _g[0], _b = _g[1];
|
||||
console.log(a);
|
||||
}
|
||||
for (var _h = 0, _j = [['key', 1]]; _h < _j.length; _h++) {
|
||||
var _k = _j[_h], _a = _k[0], _b = _k[1];
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
=== tests/cases/compiler/unusedVariablesWithUnderscoreInForOfLoop.ts ===
|
||||
function f() {
|
||||
>f : Symbol(f, Decl(unusedVariablesWithUnderscoreInForOfLoop.ts, 0, 0))
|
||||
|
||||
for (const [_a, b] of [['key', 1]]) {
|
||||
>_a : Symbol(_a, Decl(unusedVariablesWithUnderscoreInForOfLoop.ts, 1, 16))
|
||||
>b : Symbol(b, Decl(unusedVariablesWithUnderscoreInForOfLoop.ts, 1, 19))
|
||||
|
||||
console.log(b);
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>b : Symbol(b, Decl(unusedVariablesWithUnderscoreInForOfLoop.ts, 1, 19))
|
||||
}
|
||||
|
||||
for (const [a, _b] of [['key', 1]]) {
|
||||
>a : Symbol(a, Decl(unusedVariablesWithUnderscoreInForOfLoop.ts, 5, 16))
|
||||
>_b : Symbol(_b, Decl(unusedVariablesWithUnderscoreInForOfLoop.ts, 5, 18))
|
||||
|
||||
console.log(a);
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>a : Symbol(a, Decl(unusedVariablesWithUnderscoreInForOfLoop.ts, 5, 16))
|
||||
}
|
||||
|
||||
for (const [_a, _b] of [['key', 1]]) {}
|
||||
>_a : Symbol(_a, Decl(unusedVariablesWithUnderscoreInForOfLoop.ts, 9, 16))
|
||||
>_b : Symbol(_b, Decl(unusedVariablesWithUnderscoreInForOfLoop.ts, 9, 19))
|
||||
}
|
||||
|
||||
@ -0,0 +1,45 @@
|
||||
=== tests/cases/compiler/unusedVariablesWithUnderscoreInForOfLoop.ts ===
|
||||
function f() {
|
||||
>f : () => void
|
||||
|
||||
for (const [_a, b] of [['key', 1]]) {
|
||||
>_a : string | number
|
||||
>b : string | number
|
||||
>[['key', 1]] : (string | number)[][]
|
||||
>['key', 1] : (string | number)[]
|
||||
>'key' : "key"
|
||||
>1 : 1
|
||||
|
||||
console.log(b);
|
||||
>console.log(b) : void
|
||||
>console.log : (message?: any, ...optionalParams: any[]) => void
|
||||
>console : Console
|
||||
>log : (message?: any, ...optionalParams: any[]) => void
|
||||
>b : string | number
|
||||
}
|
||||
|
||||
for (const [a, _b] of [['key', 1]]) {
|
||||
>a : string | number
|
||||
>_b : string | number
|
||||
>[['key', 1]] : (string | number)[][]
|
||||
>['key', 1] : (string | number)[]
|
||||
>'key' : "key"
|
||||
>1 : 1
|
||||
|
||||
console.log(a);
|
||||
>console.log(a) : void
|
||||
>console.log : (message?: any, ...optionalParams: any[]) => void
|
||||
>console : Console
|
||||
>log : (message?: any, ...optionalParams: any[]) => void
|
||||
>a : string | number
|
||||
}
|
||||
|
||||
for (const [_a, _b] of [['key', 1]]) {}
|
||||
>_a : string | number
|
||||
>_b : string | number
|
||||
>[['key', 1]] : (string | number)[][]
|
||||
>['key', 1] : (string | number)[]
|
||||
>'key' : "key"
|
||||
>1 : 1
|
||||
}
|
||||
|
||||
@ -0,0 +1,23 @@
|
||||
tests/cases/compiler/unusedVariablesWithUnderscoreInForOfLoop1.ts(2,21): error TS6133: 'b' is declared but its value is never read.
|
||||
tests/cases/compiler/unusedVariablesWithUnderscoreInForOfLoop1.ts(4,17): error TS6133: 'a' is declared but its value is never read.
|
||||
tests/cases/compiler/unusedVariablesWithUnderscoreInForOfLoop1.ts(6,17): error TS6133: 'a' is declared but its value is never read.
|
||||
tests/cases/compiler/unusedVariablesWithUnderscoreInForOfLoop1.ts(6,20): error TS6133: 'b' is declared but its value is never read.
|
||||
|
||||
|
||||
==== tests/cases/compiler/unusedVariablesWithUnderscoreInForOfLoop1.ts (4 errors) ====
|
||||
function f() {
|
||||
for (const [_a, b] of [['key', 1]]) {}
|
||||
~
|
||||
!!! error TS6133: 'b' is declared but its value is never read.
|
||||
|
||||
for (const [a, _b] of [['key', 1]]) {}
|
||||
~
|
||||
!!! error TS6133: 'a' is declared but its value is never read.
|
||||
|
||||
for (const [a, b] of [['key', 1]]) {}
|
||||
~
|
||||
!!! error TS6133: 'a' is declared but its value is never read.
|
||||
~
|
||||
!!! error TS6133: 'b' is declared but its value is never read.
|
||||
}
|
||||
|
||||
@ -0,0 +1,22 @@
|
||||
//// [unusedVariablesWithUnderscoreInForOfLoop1.ts]
|
||||
function f() {
|
||||
for (const [_a, b] of [['key', 1]]) {}
|
||||
|
||||
for (const [a, _b] of [['key', 1]]) {}
|
||||
|
||||
for (const [a, b] of [['key', 1]]) {}
|
||||
}
|
||||
|
||||
|
||||
//// [unusedVariablesWithUnderscoreInForOfLoop1.js]
|
||||
function f() {
|
||||
for (var _i = 0, _c = [['key', 1]]; _i < _c.length; _i++) {
|
||||
var _d = _c[_i], _a = _d[0], b = _d[1];
|
||||
}
|
||||
for (var _e = 0, _f = [['key', 1]]; _e < _f.length; _e++) {
|
||||
var _g = _f[_e], a = _g[0], _b = _g[1];
|
||||
}
|
||||
for (var _h = 0, _j = [['key', 1]]; _h < _j.length; _h++) {
|
||||
var _k = _j[_h], a = _k[0], b = _k[1];
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
=== tests/cases/compiler/unusedVariablesWithUnderscoreInForOfLoop1.ts ===
|
||||
function f() {
|
||||
>f : Symbol(f, Decl(unusedVariablesWithUnderscoreInForOfLoop1.ts, 0, 0))
|
||||
|
||||
for (const [_a, b] of [['key', 1]]) {}
|
||||
>_a : Symbol(_a, Decl(unusedVariablesWithUnderscoreInForOfLoop1.ts, 1, 16))
|
||||
>b : Symbol(b, Decl(unusedVariablesWithUnderscoreInForOfLoop1.ts, 1, 19))
|
||||
|
||||
for (const [a, _b] of [['key', 1]]) {}
|
||||
>a : Symbol(a, Decl(unusedVariablesWithUnderscoreInForOfLoop1.ts, 3, 16))
|
||||
>_b : Symbol(_b, Decl(unusedVariablesWithUnderscoreInForOfLoop1.ts, 3, 18))
|
||||
|
||||
for (const [a, b] of [['key', 1]]) {}
|
||||
>a : Symbol(a, Decl(unusedVariablesWithUnderscoreInForOfLoop1.ts, 5, 16))
|
||||
>b : Symbol(b, Decl(unusedVariablesWithUnderscoreInForOfLoop1.ts, 5, 18))
|
||||
}
|
||||
|
||||
@ -0,0 +1,29 @@
|
||||
=== tests/cases/compiler/unusedVariablesWithUnderscoreInForOfLoop1.ts ===
|
||||
function f() {
|
||||
>f : () => void
|
||||
|
||||
for (const [_a, b] of [['key', 1]]) {}
|
||||
>_a : string | number
|
||||
>b : string | number
|
||||
>[['key', 1]] : (string | number)[][]
|
||||
>['key', 1] : (string | number)[]
|
||||
>'key' : "key"
|
||||
>1 : 1
|
||||
|
||||
for (const [a, _b] of [['key', 1]]) {}
|
||||
>a : string | number
|
||||
>_b : string | number
|
||||
>[['key', 1]] : (string | number)[][]
|
||||
>['key', 1] : (string | number)[]
|
||||
>'key' : "key"
|
||||
>1 : 1
|
||||
|
||||
for (const [a, b] of [['key', 1]]) {}
|
||||
>a : string | number
|
||||
>b : string | number
|
||||
>[['key', 1]] : (string | number)[][]
|
||||
>['key', 1] : (string | number)[]
|
||||
>'key' : "key"
|
||||
>1 : 1
|
||||
}
|
||||
|
||||
@ -0,0 +1,13 @@
|
||||
//@noUnusedLocals:true
|
||||
|
||||
function f() {
|
||||
for (const [_a, b] of [['key', 1]]) {
|
||||
console.log(b);
|
||||
}
|
||||
|
||||
for (const [a, _b] of [['key', 1]]) {
|
||||
console.log(a);
|
||||
}
|
||||
|
||||
for (const [_a, _b] of [['key', 1]]) {}
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
//@noUnusedLocals:true
|
||||
|
||||
function f() {
|
||||
for (const [_a, b] of [['key', 1]]) {}
|
||||
|
||||
for (const [a, _b] of [['key', 1]]) {}
|
||||
|
||||
for (const [a, b] of [['key', 1]]) {}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user