Skip to content

feat(31388): Destructuring array, ability to explicitly tell the variable is unused #41378

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33362,13 +33362,16 @@ namespace ts {
}

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"
);
if (isBindingElement(declaration)) {
if (isObjectBindingPattern(declaration.parent)) {
/**
* ignore starts with underscore names _
* const { a: _a } = { a: 1 }
*/
return !!(declaration.propertyName && isIdentifierThatStartsWithUnderscore(declaration.name));
}
return isIdentifierThatStartsWithUnderscore(declaration.name);
}

return isAmbientModule(declaration) ||
(isVariableDeclaration(declaration) && isForInOrOfStatement(declaration.parent.parent) || isImportedDeclaration(declaration)) && isIdentifierThatStartsWithUnderscore(declaration.name!);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
tests/cases/compiler/unusedVariablesWithUnderscoreInBindingElement.ts(12,17): error TS6133: 'b1' is declared but its value is never read.
tests/cases/compiler/unusedVariablesWithUnderscoreInBindingElement.ts(13,12): error TS6133: 'a2' is declared but its value is never read.
tests/cases/compiler/unusedVariablesWithUnderscoreInBindingElement.ts(14,12): error TS6133: 'a3' is declared but its value is never read.
tests/cases/compiler/unusedVariablesWithUnderscoreInBindingElement.ts(14,16): error TS6133: 'b3' is declared but its value is never read.
tests/cases/compiler/unusedVariablesWithUnderscoreInBindingElement.ts(23,12): error TS6133: 'a3' is declared but its value is never read.
tests/cases/compiler/unusedVariablesWithUnderscoreInBindingElement.ts(23,18): error TS6133: 'b3' is declared but its value is never read.
tests/cases/compiler/unusedVariablesWithUnderscoreInBindingElement.ts(23,22): error TS6133: 'c3' is declared but its value is never read.
tests/cases/compiler/unusedVariablesWithUnderscoreInBindingElement.ts(23,28): error TS6133: 'd3' is declared but its value is never read.
tests/cases/compiler/unusedVariablesWithUnderscoreInBindingElement.ts(23,32): error TS6133: 'e3' is declared but its value is never read.
tests/cases/compiler/unusedVariablesWithUnderscoreInBindingElement.ts(37,22): error TS6133: 'b1' is declared but its value is never read.
tests/cases/compiler/unusedVariablesWithUnderscoreInBindingElement.ts(38,13): error TS6133: 'a2' is declared but its value is never read.
tests/cases/compiler/unusedVariablesWithUnderscoreInBindingElement.ts(39,11): error TS6198: All destructured elements are unused.
tests/cases/compiler/unusedVariablesWithUnderscoreInBindingElement.ts(68,9): error TS6133: 'a3' is declared but its value is never read.
tests/cases/compiler/unusedVariablesWithUnderscoreInBindingElement.ts(70,18): error TS6198: All destructured elements are unused.
tests/cases/compiler/unusedVariablesWithUnderscoreInBindingElement.ts(74,9): error TS6133: 'c3' is declared but its value is never read.
tests/cases/compiler/unusedVariablesWithUnderscoreInBindingElement.ts(75,9): error TS6133: 'd3' is declared but its value is never read.
tests/cases/compiler/unusedVariablesWithUnderscoreInBindingElement.ts(81,11): error TS6198: All destructured elements are unused.


==== tests/cases/compiler/unusedVariablesWithUnderscoreInBindingElement.ts (17 errors) ====
function t1() {
const [_a1, b1] = [1, 2];
console.log(b1);

const [a2, _b2] = [1, 2];
console.log(a2);

const [_a3, _b3] = [1, 2];
}

function t2() {
const [_a1, b1] = [1, 2];
~~
!!! error TS6133: 'b1' is declared but its value is never read.
const [a2, _b2] = [1, 2];
~~
!!! error TS6133: 'a2' is declared but its value is never read.
const [a3, b3] = [1, 2];
~~
!!! error TS6133: 'a3' is declared but its value is never read.
~~
!!! error TS6133: 'b3' is declared but its value is never read.
}

function t3() {
const [_a1, [[_b1, c1]], d1, _e1] = [1, [[2, 3]], 4, 5];
console.log(c1, d1);

const [_a2, [[_b2, _c2]], _d2, _e2] = [1, [[2, 3]], 4, 5];

const [a3, [[b3, c3]], d3, e3] = [1, [[2, 3]], 4, 5];
~~
!!! error TS6133: 'a3' is declared but its value is never read.
~~
!!! error TS6133: 'b3' is declared but its value is never read.
~~
!!! error TS6133: 'c3' is declared but its value is never read.
~~
!!! error TS6133: 'd3' is declared but its value is never read.
~~
!!! error TS6133: 'e3' is declared but its value is never read.
}

function t4() {
const { a1: _a1, b1 } = { a1: 1, b1: 1 };
console.log(b1);

const { a2, b2: _b2 } = { a2: 1, b2: 1 };
console.log(a2);

const { a3: _a3, b3: _b3 } = { a3: 1, b3: 1 };
}

function t5() {
const { a1: _a1, b1 } = { a1: 1, b1: 1 };
~~
!!! error TS6133: 'b1' is declared but its value is never read.
const { a2, b2: _b2 } = { a2: 1, b2: 1 };
~~
!!! error TS6133: 'a2' is declared but its value is never read.
const { a3, b3 } = { a3: 1, b3: 1 };
~~~~~~~~~~
!!! error TS6198: All destructured elements are unused.
}

function t6() {
const {
a1: _a1,
b1: {
b11: {
b111: _b111,
b112
}
},
c1,
d1: _d1
} = { a1: 1, b1: { b11: { b111: 1, b112: 1 } }, c1: 1, d1: 1 };
console.log(b112, c1);

const {
a2: _a2,
b2: {
b21: {
b211: _b211, b212: _b212
}
},
c2: _c2,
d2: _d2
} = { a2: 1, b2: { b21: { b211: 1, b212: 1 } }, c2: 1, d2: 1 };

const {
a3,
~~
!!! error TS6133: 'a3' is declared but its value is never read.
b3: {
b31: {
~
b311, b312
~~~~~~~~~~~~~~~~~~~~~~~~~~
}
~~~~~~~~~~~~~
!!! error TS6198: All destructured elements are unused.
},
c3,
~~
!!! error TS6133: 'c3' is declared but its value is never read.
d3
~~
!!! error TS6133: 'd3' is declared but its value is never read.
} = { a3: 1, b3: { b31: { b311: 1, b312: 1 } }, c3: 1, d3: 1 };
}

function t7() {
// error
const { _a1, _b1 } = { _a1: 1, _b1: 1 };
~~~~~~~~~~~~
!!! error TS6198: All destructured elements are unused.

// ok
const { a2: _a2, b2: _b2 } = { a2: 1, b2: 1 };

// ok
const { _a3: _ignoreA3, _b3: _ignoreB3 } = { _a3: 1, _b3: 1 };
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
//// [unusedVariablesWithUnderscoreInBindingElement.ts]
function t1() {
const [_a1, b1] = [1, 2];
console.log(b1);

const [a2, _b2] = [1, 2];
console.log(a2);

const [_a3, _b3] = [1, 2];
}

function t2() {
const [_a1, b1] = [1, 2];
const [a2, _b2] = [1, 2];
const [a3, b3] = [1, 2];
}

function t3() {
const [_a1, [[_b1, c1]], d1, _e1] = [1, [[2, 3]], 4, 5];
console.log(c1, d1);

const [_a2, [[_b2, _c2]], _d2, _e2] = [1, [[2, 3]], 4, 5];

const [a3, [[b3, c3]], d3, e3] = [1, [[2, 3]], 4, 5];
}

function t4() {
const { a1: _a1, b1 } = { a1: 1, b1: 1 };
console.log(b1);

const { a2, b2: _b2 } = { a2: 1, b2: 1 };
console.log(a2);

const { a3: _a3, b3: _b3 } = { a3: 1, b3: 1 };
}

function t5() {
const { a1: _a1, b1 } = { a1: 1, b1: 1 };
const { a2, b2: _b2 } = { a2: 1, b2: 1 };
const { a3, b3 } = { a3: 1, b3: 1 };
}

function t6() {
const {
a1: _a1,
b1: {
b11: {
b111: _b111,
b112
}
},
c1,
d1: _d1
} = { a1: 1, b1: { b11: { b111: 1, b112: 1 } }, c1: 1, d1: 1 };
console.log(b112, c1);

const {
a2: _a2,
b2: {
b21: {
b211: _b211, b212: _b212
}
},
c2: _c2,
d2: _d2
} = { a2: 1, b2: { b21: { b211: 1, b212: 1 } }, c2: 1, d2: 1 };

const {
a3,
b3: {
b31: {
b311, b312
}
},
c3,
d3
} = { a3: 1, b3: { b31: { b311: 1, b312: 1 } }, c3: 1, d3: 1 };
}

function t7() {
// error
const { _a1, _b1 } = { _a1: 1, _b1: 1 };

// ok
const { a2: _a2, b2: _b2 } = { a2: 1, b2: 1 };

// ok
const { _a3: _ignoreA3, _b3: _ignoreB3 } = { _a3: 1, _b3: 1 };
}


//// [unusedVariablesWithUnderscoreInBindingElement.js]
function t1() {
var _a = [1, 2], _a1 = _a[0], b1 = _a[1];
console.log(b1);
var _b = [1, 2], a2 = _b[0], _b2 = _b[1];
console.log(a2);
var _c = [1, 2], _a3 = _c[0], _b3 = _c[1];
}
function t2() {
var _a = [1, 2], _a1 = _a[0], b1 = _a[1];
var _b = [1, 2], a2 = _b[0], _b2 = _b[1];
var _c = [1, 2], a3 = _c[0], b3 = _c[1];
}
function t3() {
var _a = [1, [[2, 3]], 4, 5], _a1 = _a[0], _b = _a[1][0], _b1 = _b[0], c1 = _b[1], d1 = _a[2], _e1 = _a[3];
console.log(c1, d1);
var _c = [1, [[2, 3]], 4, 5], _a2 = _c[0], _d = _c[1][0], _b2 = _d[0], _c2 = _d[1], _d2 = _c[2], _e2 = _c[3];
var _e = [1, [[2, 3]], 4, 5], a3 = _e[0], _f = _e[1][0], b3 = _f[0], c3 = _f[1], d3 = _e[2], e3 = _e[3];
}
function t4() {
var _a = { a1: 1, b1: 1 }, _a1 = _a.a1, b1 = _a.b1;
console.log(b1);
var _b = { a2: 1, b2: 1 }, a2 = _b.a2, _b2 = _b.b2;
console.log(a2);
var _c = { a3: 1, b3: 1 }, _a3 = _c.a3, _b3 = _c.b3;
}
function t5() {
var _a = { a1: 1, b1: 1 }, _a1 = _a.a1, b1 = _a.b1;
var _b = { a2: 1, b2: 1 }, a2 = _b.a2, _b2 = _b.b2;
var _c = { a3: 1, b3: 1 }, a3 = _c.a3, b3 = _c.b3;
}
function t6() {
var _a = { a1: 1, b1: { b11: { b111: 1, b112: 1 } }, c1: 1, d1: 1 }, _a1 = _a.a1, _b = _a.b1.b11, _b111 = _b.b111, b112 = _b.b112, c1 = _a.c1, _d1 = _a.d1;
console.log(b112, c1);
var _c = { a2: 1, b2: { b21: { b211: 1, b212: 1 } }, c2: 1, d2: 1 }, _a2 = _c.a2, _d = _c.b2.b21, _b211 = _d.b211, _b212 = _d.b212, _c2 = _c.c2, _d2 = _c.d2;
var _e = { a3: 1, b3: { b31: { b311: 1, b312: 1 } }, c3: 1, d3: 1 }, a3 = _e.a3, _f = _e.b3.b31, b311 = _f.b311, b312 = _f.b312, c3 = _e.c3, d3 = _e.d3;
}
function t7() {
// error
var _a = { _a1: 1, _b1: 1 }, _a1 = _a._a1, _b1 = _a._b1;
// ok
var _b = { a2: 1, b2: 1 }, _a2 = _b.a2, _b2 = _b.b2;
// ok
var _c = { _a3: 1, _b3: 1 }, _ignoreA3 = _c._a3, _ignoreB3 = _c._b3;
}
Loading