8000 fix(33054): allow variables starting with an underscore in for/of sta… · typescript-bot/TypeScript@d8170fa · GitHub
[go: up one dir, main page]

Skip to content
10000

Commit d8170fa

Browse files
authored
fix(33054): allow variables starting with an underscore in for/of statement (microsoft#36739)
1 parent 96f0122 commit d8170fa

10 files changed

+230
-2
lines changed

src/compiler/checker.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31013,6 +31013,18 @@ namespace ts {
3101331013
return tryCast(getRootDeclaration(node), isParameter);
3101431014
}
3101531015

31016+
function isValidUnusedLocalDeclaration(declaration: Declaration): boolean {
31017+
if (isBindingElement(declaration) && isIdentifierThatStartsWithUnderscore(declaration.name)) {
31018+
return !!findAncestor(declaration.parent, ancestor =>
31019+
isArrayBindingPattern(ancestor) || isVariableDeclaration(ancestor) || isVariableDeclarationList(ancestor) ? false :
31020+
isForOfStatement(ancestor) ? true : "quit"
31021+
);
31022+
}
31023+
31024+
return isAmbientModule(declaration) ||
31025+
(isVariableDeclaration(declaration) && isForInOrOfStatement(declaration.parent.parent) || isImportedDeclaration(declaration)) && isIdentifierThatStartsWithUnderscore(declaration.name!);
31026+
}
31027+
3101631028
function checkUnusedLocalsAndParameters(n 8000 odeWithLocals: Node, addDiagnostic: AddUnusedDiagnostic): void {
3101731029
// 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.
3101831030
const unusedImports = createMap<[ImportClause, ImportedDeclaration[]]>();
@@ -31026,8 +31038,7 @@ namespace ts {
3102631038
}
3102731039

3102831040
for (const declaration of local.declarations) {
31029-
if (isAmbientModule(declaration) ||
31030-
(isVariableDeclaration(declaration) && isForInOrOfStatement(declaration.parent.parent) || isImportedDeclaration(declaration)) && isIdentifierThatStartsWithUnderscore(declaration.name!)) {
31041+
if (isValidUnusedLocalDeclaration(declaration)) {
3103131042
continue;
3103231043
}
3103331044

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//// [unusedVariablesWithUnderscoreInForOfLoop.ts]
2+
function f() {
3+
for (const [_a, b] of [['key', 1]]) {
4+
console.log(b);
5+
}
6+
7+
for (const [a, _b] of [['key', 1]]) {
8+
console.log(a);
9+
}
10+
11+
for (const [_a, _b] of [['key', 1]]) {}
12+
}
13+
14+
15+
//// [unusedVariablesWithUnderscoreInForOfLoop.js]
16+
function f() {
17+
for (var _i = 0, _c = [['key', 1]]; _i < _c.length; _i++) {
18+
var _d = _c[_i], _a = _d[0], b = _d[1];
19+
console.log(b);
20+
}
21+
for (var _e = 0, _f = [['key', 1]]; _e < _f.length; _e++) {
22+
var _g = _f[_e], a = _g[0], _b = _g[1];
23+
console.log(a);
24+
}
25+
for (var _h = 0, _j = [['key', 1]]; _h < _j.length; _h++) {
26+
var _k = _j[_h], _a = _k[0], _b = _k[1];
27+
}
28+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
=== tests/cases/compiler/unusedVariablesWithUnderscoreInForOfLoop.ts ===
2+
function f() {
3+
>f : Symbol(f, Decl(unusedVariablesWithUnderscoreInForOfLoop.ts, 0, 0))
4+
5+
for (const [_a, b] of [['key', 1]]) {
6+
>_a : Symbol(_a, Decl(unusedVariablesWithUnderscoreInForOfLoop.ts, 1, 16))
7+
>b : Symbol(b, Decl(unusedVariablesWithUnderscoreInForOfLoop.ts, 1, 19))
8+
9+
console.log(b);
10+
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
11+
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
12+
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
13+
>b : Symbol(b, Decl(unusedVariablesWithUnderscoreInForOfLoop.ts, 1, 19))
14+
}
15+
16+
for (const [a, _b] of [['key', 1]]) {
17+
>a : Symbol(a, Decl(unusedVariablesWithUnderscoreInForOfLoop.ts, 5, 16))
18+
>_b : Symbol(_b, Decl(unusedVariablesWithUnderscoreInForOfLoop.ts, 5, 18))
19+
20+
console.log(a);
21+
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
22+
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
23+
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
24+
>a : Symbol(a, Decl(unusedVariablesWithUnderscoreInForOfLoop.ts, 5, 16))
25+
}
26+
27+
for (const [_a, _b] of [['key', 1]]) {}
28+
>_a : Symbol(_a, Decl(unusedVariablesWithUnderscoreInForOfLoop.ts, 9, 16))
29+
>_b : Symbol(_b, Decl(unusedVariablesWithUnderscoreInForOfLoop.ts, 9, 19))
30+
}
31+
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
=== tests/cases/compiler/unusedVariablesWithUnderscoreInForOfLoop.ts ===
2+
function f() {
3+
>f : () => void
4+
5+
for (const [_a, b] of [['key', 1]]) {
6+
>_a : string | number
7+
>b : string | number
8+
>[['key', 1]] : (string | number)[][]
9+
>['key', 1] : (string | number)[]
10+
>'key' : "key"
11+
>1 : 1
12+
13+
console.log(b);
14+
>console.log(b) : void
15+
>console.log : (message?: any, ...optionalParams: any[]) => void
16+
>console : Console
17+
>log : (message?: any, ...optionalParams: any[]) => void
18+
>b : string | number
19+
}
20+
21+
for (const [a, _b] of [['key', 1]]) {
22+
>a : string | number
23+
>_b : string | number
24+
>[['key', 1]] : (string | number)[][]
25+
>['key', 1] : (string | number)[]
26+
>'key' : "key"
27+
>1 : 1
28+
29+
console.log(a);
30+
>console.log(a) : void
31+
>console.log : (message?: any, ...optionalParams: any[]) => void
32+
>console : Console
33+
>log : (message?: any, ...optionalParams: any[]) => void
34+
>a : string | number
35+
}
36+
37+
for (const [_a, _b] of [['key', 1]]) {}
38+
>_a : string | number
39+
>_b : string | number
40+
>[['key', 1]] : (string | number)[][]
41+
>['key', 1] : (string | number)[]
42+
>'key' : "key"
43+
>1 : 1
44+
}
45+
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
tests/cases/compile 10000 r/unusedVariablesWithUnderscoreInForOfLoop1.ts(2,21): error TS6133: 'b' is declared but its value is never read.
2+
tests/cases/compiler/unusedVariablesWithUnderscoreInForOfLoop1.ts(4,17): error TS6133: 'a' is declared but its value is never read.
3+
tests/cases/compiler/unusedVariablesWithUnderscoreInForOfLoop1.ts(6,17): error TS6133: 'a' is declared but its value is never read.
4+
tests/cases/compiler/unusedVariablesWithUnderscoreInForOfLoop1.ts(6,20): error TS6133: 'b' is declared but its value is never read.
5+
6+
7+
==== tests/cases/compiler/unusedVariablesWithUnderscoreInForOfLoop1.ts (4 errors) ====
8+
function f() {
9+
for (const [_a, b] of [['key', 1]]) {}
10+
~
11+
!!! error TS6133: 'b' is declared but its value is never read.
12+
13+
for (const [a, _b] of [['key', 1]]) {}
14+
~
15+
!!! error TS6133: 'a' is declared but its value is never read.
16+
17+
for (const [a, b] of [['key', 1]]) {}
18+
~
19+
!!! error TS6133: 'a' is declared but its value is never read.
20+
~
21+
!!! error TS6133: 'b' is declared but its value is never read.
22+
}
23+
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//// [unusedVariablesWithUnderscoreInForOfLoop1.ts]
2+
function f() {
3+
for (const [_a, b] of [['key', 1]]) {}
4+
5+
for (const [a, _b] of [['key', 1]]) {}
6+
7+
for (const [a, b] of [['key', 1]]) {}
8+
}
9+
10+
11+
//// [unusedVariablesWithUnderscoreInForOfLoop1.js]
12+
function f() {
13+
for (var _i = 0, _c = [['key', 1]]; _i < _c.length; _i++) {
14+
var _d = _c[_i], _a = _d[0], b = _d[1];
15+
}
16+
for (var _e = 0, _f = [['key', 1]]; _e < _f.length; _e++) {
17+
var _g = _f[_e], a = _g[0], _b = _g[1];
18+
}
19+
for (var _h = 0, _j = [['key', 1]]; _h < _j.length; _h++) {
20+
var _k = _j[_h], a = _k[0], b = _k[1];
21+
}
22+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
=== tests/cases/compiler/unusedVariablesWithUnderscoreInForOfLoop1.ts ===
2+
function f() {
3+
>f : Symbol(f, Decl(unusedVariablesWithUnderscoreInForOfLoop1.ts, 0, 0))
4+
5+
for (const [_a, b] of [['key', 1]]) {}
6+
>_a : Symbol(_a, Decl(unusedVariablesWithUnderscoreInForOfLoop1.ts, 1, 16))
7+
>b : Symbol(b, Decl(unusedVariablesWithUnderscoreInForOfLoop1.ts, 1, 19))
8+
9+
for (const [a, _b] of [['key', 1]]) {}
10+
>a : Symbol(a, Decl(unusedVariablesWithUnderscoreInForOfLoop1.ts, 3, 16))
11+
>_b : Symbol(_b, Decl(unusedVariablesWithUnderscoreInForOfLoop1.ts, 3, 18))
12+
13+
for (const [a, b] of [['key', 1]]) {}
14+
>a : Symbol(a, Decl(unusedVariablesWithUnderscoreInForOfLoop1.ts, 5, 16))
15+
>b : Symbol(b, Decl(unusedVariablesWithUnderscoreInForOfLoop1.ts, 5, 18))
16+
}
17+
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
=== tests/cases/compiler/unusedVariablesWithUnderscoreInForOfLoop1.ts ===
2+
function f() {
3+
>f : () => void
4+
5+
for (const [_a, b] of [['key', 1]]) {}
6+
>_a : string | number
7+
>b : string | number
8+
>[['key', 1]] : (string | number)[][]
9+
>['key', 1] : (string | number)[]
10+
>'key' : "key"
11+
>1 : 1
12+
13+
for (const [a, _b] of [['key', 1]]) {}
14+
>a : string | number
15+
>_b : string | number
16+
>[['key', 1]] : (string | number)[][]
17+
>['key', 1] : (string | number)[]
18+
>'key' : "key"
19+
>1 : 1
20+
21+
for (const [a, b] of [['key', 1]]) {}
22+
>a : string | number
23+
>b : string | number
24+
>[['key', 1]] : (string | number)[][]
25+
>['key', 1] : (string | number)[]
26+
>'key' : "key"
27+
>1 : 1
28+
}
29+
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//@noUnusedLocals:true
2+
3+
function f() {
4+
for (const [_a, b] of [['key', 1]]) {
5+
console.log(b);
6+
}
7+
8+
for (const [a, _b] of [['key', 1]]) {
9+
console.log(a);
10+
}
11+
12+
for (const [_a, _b] of [['key', 1]]) {}
13+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
//@noUnusedLocals:true
2+
3+
function f() {
4+
for (const [_a, b] of [['key', 1]]) {}
5+
6+
for (const [a, _b] of [['key', 1]]) {}
7+
8+
for (const [a, b] of [['key', 1]]) {}
9+
}

0 commit comments

Comments
 (0)
0