diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 75be36474222f..5c93d02015ec7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -44409,21 +44409,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return tryCast(getRootDeclaration(node), isParameter); } - function isValidUnusedLocalDeclaration(declaration: Declaration): boolean { - 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!); - } - function checkUnusedLocalsAndParameters(nodeWithLocals: HasLocals, 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 = new Map(); @@ -44438,7 +44423,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (local.declarations) { for (const declaration of local.declarations) { - if (isValidUnusedLocalDeclaration(declaration)) { + const name = getNameOfDeclaration(declaration); + if (isAmbientModule(declaration) || name && isIdentifierThatStartsWithUnderscore(name)) { continue; } diff --git a/tests/baselines/reference/noUnusedLocals_types.errors.txt b/tests/baselines/reference/noUnusedLocals_types.errors.txt new file mode 100644 index 0000000000000..e2aefdbe8d642 --- /dev/null +++ b/tests/baselines/reference/noUnusedLocals_types.errors.txt @@ -0,0 +1,29 @@ +noUnusedLocals_types.ts(4,6): error TS6196: 'UnusedType1' is declared but never used. +noUnusedLocals_types.ts(5,11): error TS6196: 'UnusedInterface1' is declared but never used. +noUnusedLocals_types.ts(6,7): error TS6196: 'UnusedClass1' is declared but never used. + + +==== noUnusedLocals_types.ts (3 errors) ==== + // Test specifically for type declarations with underscore prefix + + // These should all produce errors (no underscore) + type UnusedType1 = string; + ~~~~~~~~~~~ +!!! error TS6196: 'UnusedType1' is declared but never used. + interface UnusedInterface1 { x: number; } + ~~~~~~~~~~~~~~~~ +!!! error TS6196: 'UnusedInterface1' is declared but never used. + class UnusedClass1 { } + ~~~~~~~~~~~~ +!!! error TS6196: 'UnusedClass1' is declared but never used. + + // These should NOT produce errors (underscore prefix) + type _UnusedType2 = string; + interface _UnusedInterface2 { x: number; } + class _UnusedClass2 { } + + // Mixed usage - only the one without underscore should error + type UsedInOther = number; + type _Helper = UsedInOther; // _Helper is not an error, but it uses UsedInOther + + export {}; \ No newline at end of file diff --git a/tests/baselines/reference/noUnusedLocals_types.js b/tests/baselines/reference/noUnusedLocals_types.js new file mode 100644 index 0000000000000..dad514b77b336 --- /dev/null +++ b/tests/baselines/reference/noUnusedLocals_types.js @@ -0,0 +1,35 @@ +//// [tests/cases/compiler/noUnusedLocals_types.ts] //// + +//// [noUnusedLocals_types.ts] +// Test specifically for type declarations with underscore prefix + +// These should all produce errors (no underscore) +type UnusedType1 = string; +interface UnusedInterface1 { x: number; } +class UnusedClass1 { } + +// These should NOT produce errors (underscore prefix) +type _UnusedType2 = string; +interface _UnusedInterface2 { x: number; } +class _UnusedClass2 { } + +// Mixed usage - only the one without underscore should error +type UsedInOther = number; +type _Helper = UsedInOther; // _Helper is not an error, but it uses UsedInOther + +export {}; + +//// [noUnusedLocals_types.js] +"use strict"; +// Test specifically for type declarations with underscore prefix +Object.defineProperty(exports, "__esModule", { value: true }); +var UnusedClass1 = /** @class */ (function () { + function UnusedClass1() { + } + return UnusedClass1; +}()); +var _UnusedClass2 = /** @class */ (function () { + function _UnusedClass2() { + } + return _UnusedClass2; +}()); diff --git a/tests/baselines/reference/noUnusedLocals_types.symbols b/tests/baselines/reference/noUnusedLocals_types.symbols new file mode 100644 index 0000000000000..27da3839cd1e5 --- /dev/null +++ b/tests/baselines/reference/noUnusedLocals_types.symbols @@ -0,0 +1,36 @@ +//// [tests/cases/compiler/noUnusedLocals_types.ts] //// + +=== noUnusedLocals_types.ts === +// Test specifically for type declarations with underscore prefix + +// These should all produce errors (no underscore) +type UnusedType1 = string; +>UnusedType1 : Symbol(UnusedType1, Decl(noUnusedLocals_types.ts, 0, 0)) + +interface UnusedInterface1 { x: number; } +>UnusedInterface1 : Symbol(UnusedInterface1, Decl(noUnusedLocals_types.ts, 3, 26)) +>x : Symbol(UnusedInterface1.x, Decl(noUnusedLocals_types.ts, 4, 28)) + +class UnusedClass1 { } +>UnusedClass1 : Symbol(UnusedClass1, Decl(noUnusedLocals_types.ts, 4, 41)) + +// These should NOT produce errors (underscore prefix) +type _UnusedType2 = string; +>_UnusedType2 : Symbol(_UnusedType2, Decl(noUnusedLocals_types.ts, 5, 22)) + +interface _UnusedInterface2 { x: number; } +>_UnusedInterface2 : Symbol(_UnusedInterface2, Decl(noUnusedLocals_types.ts, 8, 27)) +>x : Symbol(_UnusedInterface2.x, Decl(noUnusedLocals_types.ts, 9, 29)) + +class _UnusedClass2 { } +>_UnusedClass2 : Symbol(_UnusedClass2, Decl(noUnusedLocals_types.ts, 9, 42)) + +// Mixed usage - only the one without underscore should error +type UsedInOther = number; +>UsedInOther : Symbol(UsedInOther, Decl(noUnusedLocals_types.ts, 10, 23)) + +type _Helper = UsedInOther; // _Helper is not an error, but it uses UsedInOther +>_Helper : Symbol(_Helper, Decl(noUnusedLocals_types.ts, 13, 26)) +>UsedInOther : Symbol(UsedInOther, Decl(noUnusedLocals_types.ts, 10, 23)) + +export {}; diff --git a/tests/baselines/reference/noUnusedLocals_types.types b/tests/baselines/reference/noUnusedLocals_types.types new file mode 100644 index 0000000000000..c8c72a147bb25 --- /dev/null +++ b/tests/baselines/reference/noUnusedLocals_types.types @@ -0,0 +1,41 @@ +//// [tests/cases/compiler/noUnusedLocals_types.ts] //// + +=== noUnusedLocals_types.ts === +// Test specifically for type declarations with underscore prefix + +// These should all produce errors (no underscore) +type UnusedType1 = string; +>UnusedType1 : string +> : ^^^^^^ + +interface UnusedInterface1 { x: number; } +>x : number +> : ^^^^^^ + +class UnusedClass1 { } +>UnusedClass1 : UnusedClass1 +> : ^^^^^^^^^^^^ + +// These should NOT produce errors (underscore prefix) +type _UnusedType2 = string; +>_UnusedType2 : string +> : ^^^^^^ + +interface _UnusedInterface2 { x: number; } +>x : number +> : ^^^^^^ + +class _UnusedClass2 { } +>_UnusedClass2 : _UnusedClass2 +> : ^^^^^^^^^^^^^ + +// Mixed usage - only the one without underscore should error +type UsedInOther = number; +>UsedInOther : number +> : ^^^^^^ + +type _Helper = UsedInOther; // _Helper is not an error, but it uses UsedInOther +>_Helper : number +> : ^^^^^^ + +export {}; diff --git a/tests/baselines/reference/unusedLocalsStartingWithUnderscore.errors.txt b/tests/baselines/reference/unusedLocalsStartingWithUnderscore.errors.txt index 4a708b6aa8725..52464b16fe632 100644 --- a/tests/baselines/reference/unusedLocalsStartingWithUnderscore.errors.txt +++ b/tests/baselines/reference/unusedLocalsStartingWithUnderscore.errors.txt @@ -1,22 +1,156 @@ -/a.ts(7,11): error TS6133: '_ns' is declared but its value is never read. -/a.ts(8,9): error TS6133: '_' is declared but its value is never read. +unusedLocalsStartingWithUnderscore.ts(2,7): error TS6133: 'unusedVar' is declared but its value is never read. +unusedLocalsStartingWithUnderscore.ts(5,5): error TS6133: 'unusedLet' is declared but its value is never read. +unusedLocalsStartingWithUnderscore.ts(8,5): error TS6133: 'unusedVar2' is declared but its value is never read. +unusedLocalsStartingWithUnderscore.ts(11,9): error TS6133: 'a1' is declared but its value is never read. +unusedLocalsStartingWithUnderscore.ts(15,10): error TS6133: 'unusedFunc' is declared but its value is never read. +unusedLocalsStartingWithUnderscore.ts(18,7): error TS6133: 'unusedArrow' is declared but its value is never read. +unusedLocalsStartingWithUnderscore.ts(22,7): error TS6196: 'UnusedClass' is declared but never used. +unusedLocalsStartingWithUnderscore.ts(26,11): error TS6196: 'UnusedInterface' is declared but never used. +unusedLocalsStartingWithUnderscore.ts(30,6): error TS6196: 'UnusedType' is declared but never used. +unusedLocalsStartingWithUnderscore.ts(34,6): error TS6196: 'UnusedEnum' is declared but never used. +unusedLocalsStartingWithUnderscore.ts(39,12): error TS6133: 'x' is declared but its value is never read. +unusedLocalsStartingWithUnderscore.ts(41,12): error TS6133: 'x' is declared but its value is never read. +unusedLocalsStartingWithUnderscore.ts(44,11): error TS6133: 'UnusedNamespace' is declared but its value is never read. +unusedLocalsStartingWithUnderscore.ts(52,7): error TS6133: 'unusedA' is declared but its value is never read. +unusedLocalsStartingWithUnderscore.ts(54,8): error TS6133: 'unusedC' is declared but its value is never read. +unusedLocalsStartingWithUnderscore.ts(61,7): error TS6196: 'TestClass' is declared but never used. +unusedLocalsStartingWithUnderscore.ts(62,13): error TS6133: 'unusedMember' is declared but its value is never read. +unusedLocalsStartingWithUnderscore.ts(63,13): error TS6133: '_unusedMember' is declared but its value is never read. +unusedLocalsStartingWithUnderscore.ts(65,13): error TS6133: 'unusedMethod' is declared but its value is never read. +unusedLocalsStartingWithUnderscore.ts(66,13): error TS6133: '_unusedMethod' is declared but its value is never read. +unusedLocalsStartingWithUnderscore.ts(69,6): error TS6196: 'TestEnum' is declared but never used. +unusedLocalsStartingWithUnderscore.ts(74,11): error TS6196: 'TestInterface' is declared but never used. +unusedLocalsStartingWithUnderscore.ts(79,7): error TS6133: 'obj' is declared but its value is never read. -==== /a.ts (2 errors) ==== - import * as _ from "./a"; +==== unusedLocalsStartingWithUnderscore.ts (23 errors) ==== + // Variables + const unusedVar = 1; // error + ~~~~~~~~~ +!!! error TS6133: 'unusedVar' is declared but its value is never read. + const _unusedVar = 2; // ok - for (const _ of []) { } + let unusedLet = 3; // error + ~~~~~~~~~ +!!! error TS6133: 'unusedLet' is declared but its value is never read. + let _unusedLet = 4; // ok - for (const _ in []) { } + var unusedVar2 = 5; // error + ~~~~~~~~~~ +!!! error TS6133: 'unusedVar2' is declared but its value is never read. + var _unusedVar2 = 6; // ok - namespace _ns { - ~~~ -!!! error TS6133: '_ns' is declared but its value is never read. - let _; - ~ -!!! error TS6133: '_' is declared but its value is never read. - for (const _ of []) { } + const { a1, _b1 } = { a1: 1, _b1: 2 }; // error on a1 + ~~ +!!! error TS6133: 'a1' is declared but its value is never read. + const { _a2, _b2 } = { _a2: 1, _b2: 2 }; // ok - for (const _ in []) { } + // Functions + function unusedFunc() { } // error + ~~~~~~~~~~ +!!! error TS6133: 'unusedFunc' is declared but its value is never read. + function _unusedFunc() { } // ok + + const unusedArrow = () => { }; // error + ~~~~~~~~~~~ +!!! error TS6133: 'unusedArrow' is declared but its value is never read. + const _unusedArrow = () => { }; // ok + + // Classes + class UnusedClass { } // error + ~~~~~~~~~~~ +!!! error TS6196: 'UnusedClass' is declared but never used. + class _UnusedClass { } // ok + + // Interfaces + interface UnusedInterface { } // error + ~~~~~~~~~~~~~~~ +!!! error TS6196: 'UnusedInterface' is declared but never used. + interface _UnusedInterface { } // ok + + // Type aliases + type UnusedType = string; // error + ~~~~~~~~~~ +!!! error TS6196: 'UnusedType' is declared but never used. + type _UnusedType = string; // ok + + // Enums + enum UnusedEnum { A } // error + ~~~~~~~~~~ +!!! error TS6196: 'UnusedEnum' is declared but never used. + enum _UnusedEnum { A } // ok + + // Declarations in for loops + for (const _x of []) { } // ok + for (const x of []) { } // error + ~ +!!! error TS6133: 'x' is declared but its value is never read. + for (const _x in []) { } // ok + for (const x in []) { } // error + ~ +!!! error TS6133: 'x' is declared but its value is never read. + + // Namespaces + namespace UnusedNamespace { // error + ~~~~~~~~~~~~~~~ +!!! error TS6133: 'UnusedNamespace' is declared but its value is never read. + export const x = 1; + } + namespace _UnusedNamespace { // ok + export const x = 1; } - \ No newline at end of file + + // Destructuring + const { a: unusedA } = { a: 1 }; // error + ~~~~~~~~~~~~~~ +!!! error TS6133: 'unusedA' is declared but its value is never read. + const { b: _unusedB } = { b: 2 }; // ok + const [unusedC] = [3]; // error + ~~~~~~~ +!!! error TS6133: 'unusedC' is declared but its value is never read. + const [_unusedD] = [4]; // ok + + // + // The following declarations may _not_ use an underscore to bypass @noUnusedLocals + // + + class TestClass { + ~~~~~~~~~ +!!! error TS6196: 'TestClass' is declared but never used. + private unusedMember = 1; // error + ~~~~~~~~~~~~ +!!! error TS6133: 'unusedMember' is declared but its value is never read. + private _unusedMember = 2; // still error + ~~~~~~~~~~~~~ +!!! error TS6133: '_unusedMember' is declared but its value is never read. + + private unusedMethod() { } // error + ~~~~~~~~~~~~ +!!! error TS6133: 'unusedMethod' is declared but its value is never read. + private _unusedMethod() { } // still error + ~~~~~~~~~~~~~ +!!! error TS6133: '_unusedMethod' is declared but its value is never read. + } + + enum TestEnum { + ~~~~~~~~ +!!! error TS6196: 'TestEnum' is declared but never used. + UnusedMember = 1, // error + _UnusedMember = 2, // still error + } + + interface TestInterface { + ~~~~~~~~~~~~~ +!!! error TS6196: 'TestInterface' is declared but never used. + unusedProp: number; // error + _unusedProp: number; // still error + } + + const obj = { + ~~~ +!!! error TS6133: 'obj' is declared but its value is never read. + unusedProp: 1, // error + _unusedProp: 2, // still error + }; + + export { }; \ No newline at end of file diff --git a/tests/baselines/reference/unusedLocalsStartingWithUnderscore.js b/tests/baselines/reference/unusedLocalsStartingWithUnderscore.js index 6aef10f7e34d7..c7509cf7f6f30 100644 --- a/tests/baselines/reference/unusedLocalsStartingWithUnderscore.js +++ b/tests/baselines/reference/unusedLocalsStartingWithUnderscore.js @@ -1,32 +1,169 @@ //// [tests/cases/compiler/unusedLocalsStartingWithUnderscore.ts] //// -//// [a.ts] -import * as _ from "./a"; +//// [unusedLocalsStartingWithUnderscore.ts] +// Variables +const unusedVar = 1; // error +const _unusedVar = 2; // ok -for (const _ of []) { } +let unusedLet = 3; // error +let _unusedLet = 4; // ok -for (const _ in []) { } +var unusedVar2 = 5; // error +var _unusedVar2 = 6; // ok -namespace _ns { - let _; - for (const _ of []) { } +const { a1, _b1 } = { a1: 1, _b1: 2 }; // error on a1 +const { _a2, _b2 } = { _a2: 1, _b2: 2 }; // ok - for (const _ in []) { } +// Functions +function unusedFunc() { } // error +function _unusedFunc() { } // ok + +const unusedArrow = () => { }; // error +const _unusedArrow = () => { }; // ok + +// Classes +class UnusedClass { } // error +class _UnusedClass { } // ok + +// Interfaces +interface UnusedInterface { } // error +interface _UnusedInterface { } // ok + +// Type aliases +type UnusedType = string; // error +type _UnusedType = string; // ok + +// Enums +enum UnusedEnum { A } // error +enum _UnusedEnum { A } // ok + +// Declarations in for loops +for (const _x of []) { } // ok +for (const x of []) { } // error +for (const _x in []) { } // ok +for (const x in []) { } // error + +// Namespaces +namespace UnusedNamespace { // error + export const x = 1; } +namespace _UnusedNamespace { // ok + export const x = 1; +} + +// Destructuring +const { a: unusedA } = { a: 1 }; // error +const { b: _unusedB } = { b: 2 }; // ok +const [unusedC] = [3]; // error +const [_unusedD] = [4]; // ok + +// +// The following declarations may _not_ use an underscore to bypass @noUnusedLocals +// + +class TestClass { + private unusedMember = 1; // error + private _unusedMember = 2; // still error + + private unusedMethod() { } // error + private _unusedMethod() { } // still error +} + +enum TestEnum { + UnusedMember = 1, // error + _UnusedMember = 2, // still error +} + +interface TestInterface { + unusedProp: number; // error + _unusedProp: number; // still error +} + +const obj = { + unusedProp: 1, // error + _unusedProp: 2, // still error +}; + +export { }; - -//// [a.js] +//// [unusedLocalsStartingWithUnderscore.js] "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -for (var _i = 0, _a = []; _i < _a.length; _i++) { - var _1 = _a[_i]; -} -for (var _2 in []) { } -var _ns; -(function (_ns) { - var _; - for (var _i = 0, _a = []; _i < _a.length; _i++) { - var _3 = _a[_i]; +// Variables +var unusedVar = 1; // error +var _unusedVar = 2; // ok +var unusedLet = 3; // error +var _unusedLet = 4; // ok +var unusedVar2 = 5; // error +var _unusedVar2 = 6; // ok +var _a = { a1: 1, _b1: 2 }, a1 = _a.a1, _b1 = _a._b1; // error on a1 +var _b = { _a2: 1, _b2: 2 }, _a2 = _b._a2, _b2 = _b._b2; // ok +// Functions +function unusedFunc() { } // error +function _unusedFunc() { } // ok +var unusedArrow = function () { }; // error +var _unusedArrow = function () { }; // ok +// Classes +var UnusedClass = /** @class */ (function () { + function UnusedClass() { + } + return UnusedClass; +}()); // error +var _UnusedClass = /** @class */ (function () { + function _UnusedClass() { + } + return _UnusedClass; +}()); // ok +// Enums +var UnusedEnum; +(function (UnusedEnum) { + UnusedEnum[UnusedEnum["A"] = 0] = "A"; +})(UnusedEnum || (UnusedEnum = {})); // error +var _UnusedEnum; +(function (_UnusedEnum) { + _UnusedEnum[_UnusedEnum["A"] = 0] = "A"; +})(_UnusedEnum || (_UnusedEnum = {})); // ok +// Declarations in for loops +for (var _i = 0, _c = []; _i < _c.length; _i++) { + var _x = _c[_i]; +} // ok +for (var _d = 0, _e = []; _d < _e.length; _d++) { + var x = _e[_d]; +} // error +for (var _x in []) { } // ok +for (var x in []) { } // error +// Namespaces +var UnusedNamespace; +(function (UnusedNamespace) { + UnusedNamespace.x = 1; +})(UnusedNamespace || (UnusedNamespace = {})); +var _UnusedNamespace; +(function (_UnusedNamespace) { + _UnusedNamespace.x = 1; +})(_UnusedNamespace || (_UnusedNamespace = {})); +// Destructuring +var unusedA = { a: 1 }.a; // error +var _unusedB = { b: 2 }.b; // ok +var unusedC = [3][0]; // error +var _unusedD = [4][0]; // ok +// +// The following declarations may _not_ use an underscore to bypass @noUnusedLocals +// +var TestClass = /** @class */ (function () { + function TestClass() { + this.unusedMember = 1; // error + this._unusedMember = 2; // still error } - for (var _4 in []) { } -})(_ns || (_ns = {})); + TestClass.prototype.unusedMethod = function () { }; // error + TestClass.prototype._unusedMethod = function () { }; // still error + return TestClass; +}()); +var TestEnum; +(function (TestEnum) { + TestEnum[TestEnum["UnusedMember"] = 1] = "UnusedMember"; + TestEnum[TestEnum["_UnusedMember"] = 2] = "_UnusedMember"; +})(TestEnum || (TestEnum = {})); +var obj = { + unusedProp: 1, // error + _unusedProp: 2, // still error +}; diff --git a/tests/baselines/reference/unusedLocalsStartingWithUnderscore.symbols b/tests/baselines/reference/unusedLocalsStartingWithUnderscore.symbols index 6c251dc237e90..fbabe635f0a44 100644 --- a/tests/baselines/reference/unusedLocalsStartingWithUnderscore.symbols +++ b/tests/baselines/reference/unusedLocalsStartingWithUnderscore.symbols @@ -1,25 +1,173 @@ //// [tests/cases/compiler/unusedLocalsStartingWithUnderscore.ts] //// -=== /a.ts === -import * as _ from "./a"; ->_ : Symbol(_, Decl(a.ts, 0, 6)) +=== unusedLocalsStartingWithUnderscore.ts === +// Variables +const unusedVar = 1; // error +>unusedVar : Symbol(unusedVar, Decl(unusedLocalsStartingWithUnderscore.ts, 1, 5)) -for (const _ of []) { } ->_ : Symbol(_, Decl(a.ts, 2, 10)) +const _unusedVar = 2; // ok +>_unusedVar : Symbol(_unusedVar, Decl(unusedLocalsStartingWithUnderscore.ts, 2, 5)) -for (const _ in []) { } ->_ : Symbol(_, Decl(a.ts, 4, 10)) +let unusedLet = 3; // error +>unusedLet : Symbol(unusedLet, Decl(unusedLocalsStartingWithUnderscore.ts, 4, 3)) -namespace _ns { ->_ns : Symbol(_ns, Decl(a.ts, 4, 23)) +let _unusedLet = 4; // ok +>_unusedLet : Symbol(_unusedLet, Decl(unusedLocalsStartingWithUnderscore.ts, 5, 3)) - let _; ->_ : Symbol(_, Decl(a.ts, 7, 7)) +var unusedVar2 = 5; // error +>unusedVar2 : Symbol(unusedVar2, Decl(unusedLocalsStartingWithUnderscore.ts, 7, 3)) - for (const _ of []) { } ->_ : Symbol(_, Decl(a.ts, 8, 14)) +var _unusedVar2 = 6; // ok +>_unusedVar2 : Symbol(_unusedVar2, Decl(unusedLocalsStartingWithUnderscore.ts, 8, 3)) - for (const _ in []) { } ->_ : Symbol(_, Decl(a.ts, 10, 14)) +const { a1, _b1 } = { a1: 1, _b1: 2 }; // error on a1 +>a1 : Symbol(a1, Decl(unusedLocalsStartingWithUnderscore.ts, 10, 7)) +>_b1 : Symbol(_b1, Decl(unusedLocalsStartingWithUnderscore.ts, 10, 11)) +>a1 : Symbol(a1, Decl(unusedLocalsStartingWithUnderscore.ts, 10, 21)) +>_b1 : Symbol(_b1, Decl(unusedLocalsStartingWithUnderscore.ts, 10, 28)) + +const { _a2, _b2 } = { _a2: 1, _b2: 2 }; // ok +>_a2 : Symbol(_a2, Decl(unusedLocalsStartingWithUnderscore.ts, 11, 7)) +>_b2 : Symbol(_b2, Decl(unusedLocalsStartingWithUnderscore.ts, 11, 12)) +>_a2 : Symbol(_a2, Decl(unusedLocalsStartingWithUnderscore.ts, 11, 22)) +>_b2 : Symbol(_b2, Decl(unusedLocalsStartingWithUnderscore.ts, 11, 30)) + +// Functions +function unusedFunc() { } // error +>unusedFunc : Symbol(unusedFunc, Decl(unusedLocalsStartingWithUnderscore.ts, 11, 40)) + +function _unusedFunc() { } // ok +>_unusedFunc : Symbol(_unusedFunc, Decl(unusedLocalsStartingWithUnderscore.ts, 14, 25)) + +const unusedArrow = () => { }; // error +>unusedArrow : Symbol(unusedArrow, Decl(unusedLocalsStartingWithUnderscore.ts, 17, 5)) + +const _unusedArrow = () => { }; // ok +>_unusedArrow : Symbol(_unusedArrow, Decl(unusedLocalsStartingWithUnderscore.ts, 18, 5)) + +// Classes +class UnusedClass { } // error +>UnusedClass : Symbol(UnusedClass, Decl(unusedLocalsStartingWithUnderscore.ts, 18, 31)) + +class _UnusedClass { } // ok +>_UnusedClass : Symbol(_UnusedClass, Decl(unusedLocalsStartingWithUnderscore.ts, 21, 21)) + +// Interfaces +interface UnusedInterface { } // error +>UnusedInterface : Symbol(UnusedInterface, Decl(unusedLocalsStartingWithUnderscore.ts, 22, 22)) + +interface _UnusedInterface { } // ok +>_UnusedInterface : Symbol(_UnusedInterface, Decl(unusedLocalsStartingWithUnderscore.ts, 25, 29)) + +// Type aliases +type UnusedType = string; // error +>UnusedType : Symbol(UnusedType, Decl(unusedLocalsStartingWithUnderscore.ts, 26, 30)) + +type _UnusedType = string; // ok +>_UnusedType : Symbol(_UnusedType, Decl(unusedLocalsStartingWithUnderscore.ts, 29, 25)) + +// Enums +enum UnusedEnum { A } // error +>UnusedEnum : Symbol(UnusedEnum, Decl(unusedLocalsStartingWithUnderscore.ts, 30, 26)) +>A : Symbol(UnusedEnum.A, Decl(unusedLocalsStartingWithUnderscore.ts, 33, 17)) + +enum _UnusedEnum { A } // ok +>_UnusedEnum : Symbol(_UnusedEnum, Decl(unusedLocalsStartingWithUnderscore.ts, 33, 21)) +>A : Symbol(_UnusedEnum.A, Decl(unusedLocalsStartingWithUnderscore.ts, 34, 18)) + +// Declarations in for loops +for (const _x of []) { } // ok +>_x : Symbol(_x, Decl(unusedLocalsStartingWithUnderscore.ts, 37, 10)) + +for (const x of []) { } // error +>x : Symbol(x, Decl(unusedLocalsStartingWithUnderscore.ts, 38, 10)) + +for (const _x in []) { } // ok +>_x : Symbol(_x, Decl(unusedLocalsStartingWithUnderscore.ts, 39, 10)) + +for (const x in []) { } // error +>x : Symbol(x, Decl(unusedLocalsStartingWithUnderscore.ts, 40, 10)) + +// Namespaces +namespace UnusedNamespace { // error +>UnusedNamespace : Symbol(UnusedNamespace, Decl(unusedLocalsStartingWithUnderscore.ts, 40, 23)) + + export const x = 1; +>x : Symbol(x, Decl(unusedLocalsStartingWithUnderscore.ts, 44, 16)) +} +namespace _UnusedNamespace { // ok +>_UnusedNamespace : Symbol(_UnusedNamespace, Decl(unusedLocalsStartingWithUnderscore.ts, 45, 1)) + + export const x = 1; +>x : Symbol(x, Decl(unusedLocalsStartingWithUnderscore.ts, 47, 16)) +} + +// Destructuring +const { a: unusedA } = { a: 1 }; // error +>a : Symbol(a, Decl(unusedLocalsStartingWithUnderscore.ts, 51, 24)) +>unusedA : Symbol(unusedA, Decl(unusedLocalsStartingWithUnderscore.ts, 51, 7)) +>a : Symbol(a, Decl(unusedLocalsStartingWithUnderscore.ts, 51, 24)) + +const { b: _unusedB } = { b: 2 }; // ok +>b : Symbol(b, Decl(unusedLocalsStartingWithUnderscore.ts, 52, 25)) +>_unusedB : Symbol(_unusedB, Decl(unusedLocalsStartingWithUnderscore.ts, 52, 7)) +>b : Symbol(b, Decl(unusedLocalsStartingWithUnderscore.ts, 52, 25)) + +const [unusedC] = [3]; // error +>unusedC : Symbol(unusedC, Decl(unusedLocalsStartingWithUnderscore.ts, 53, 7)) + +const [_unusedD] = [4]; // ok +>_unusedD : Symbol(_unusedD, Decl(unusedLocalsStartingWithUnderscore.ts, 54, 7)) + +// +// The following declarations may _not_ use an underscore to bypass @noUnusedLocals +// + +class TestClass { +>TestClass : Symbol(TestClass, Decl(unusedLocalsStartingWithUnderscore.ts, 54, 23)) + + private unusedMember = 1; // error +>unusedMember : Symbol(TestClass.unusedMember, Decl(unusedLocalsStartingWithUnderscore.ts, 60, 17)) + + private _unusedMember = 2; // still error +>_unusedMember : Symbol(TestClass._unusedMember, Decl(unusedLocalsStartingWithUnderscore.ts, 61, 29)) + + private unusedMethod() { } // error +>unusedMethod : Symbol(TestClass.unusedMethod, Decl(unusedLocalsStartingWithUnderscore.ts, 62, 30)) + + private _unusedMethod() { } // still error +>_unusedMethod : Symbol(TestClass._unusedMethod, Decl(unusedLocalsStartingWithUnderscore.ts, 64, 30)) +} + +enum TestEnum { +>TestEnum : Symbol(TestEnum, Decl(unusedLocalsStartingWithUnderscore.ts, 66, 1)) + + UnusedMember = 1, // error +>UnusedMember : Symbol(TestEnum.UnusedMember, Decl(unusedLocalsStartingWithUnderscore.ts, 68, 15)) + + _UnusedMember = 2, // still error +>_UnusedMember : Symbol(TestEnum._UnusedMember, Decl(unusedLocalsStartingWithUnderscore.ts, 69, 21)) } +interface TestInterface { +>TestInterface : Symbol(TestInterface, Decl(unusedLocalsStartingWithUnderscore.ts, 71, 1)) + + unusedProp: number; // error +>unusedProp : Symbol(TestInterface.unusedProp, Decl(unusedLocalsStartingWithUnderscore.ts, 73, 25)) + + _unusedProp: number; // still error +>_unusedProp : Symbol(TestInterface._unusedProp, Decl(unusedLocalsStartingWithUnderscore.ts, 74, 23)) +} + +const obj = { +>obj : Symbol(obj, Decl(unusedLocalsStartingWithUnderscore.ts, 78, 5)) + + unusedProp: 1, // error +>unusedProp : Symbol(unusedProp, Decl(unusedLocalsStartingWithUnderscore.ts, 78, 13)) + + _unusedProp: 2, // still error +>_unusedProp : Symbol(_unusedProp, Decl(unusedLocalsStartingWithUnderscore.ts, 79, 18)) + +}; + +export { }; diff --git a/tests/baselines/reference/unusedLocalsStartingWithUnderscore.types b/tests/baselines/reference/unusedLocalsStartingWithUnderscore.types index 834f3ef6e467d..2e2539f4bc41b 100644 --- a/tests/baselines/reference/unusedLocalsStartingWithUnderscore.types +++ b/tests/baselines/reference/unusedLocalsStartingWithUnderscore.types @@ -1,40 +1,293 @@ //// [tests/cases/compiler/unusedLocalsStartingWithUnderscore.ts] //// -=== /a.ts === -import * as _ from "./a"; ->_ : typeof _ -> : ^^^^^^^^ +=== unusedLocalsStartingWithUnderscore.ts === +// Variables +const unusedVar = 1; // error +>unusedVar : 1 +> : ^ +>1 : 1 +> : ^ -for (const _ of []) { } ->_ : any +const _unusedVar = 2; // ok +>_unusedVar : 2 +> : ^ +>2 : 2 +> : ^ + +let unusedLet = 3; // error +>unusedLet : number +> : ^^^^^^ +>3 : 3 +> : ^ + +let _unusedLet = 4; // ok +>_unusedLet : number +> : ^^^^^^ +>4 : 4 +> : ^ + +var unusedVar2 = 5; // error +>unusedVar2 : number +> : ^^^^^^ +>5 : 5 +> : ^ + +var _unusedVar2 = 6; // ok +>_unusedVar2 : number +> : ^^^^^^ +>6 : 6 +> : ^ + +const { a1, _b1 } = { a1: 1, _b1: 2 }; // error on a1 +>a1 : number +> : ^^^^^^ +>_b1 : number +> : ^^^^^^ +>{ a1: 1, _b1: 2 } : { a1: number; _b1: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>a1 : number +> : ^^^^^^ +>1 : 1 +> : ^ +>_b1 : number +> : ^^^^^^ +>2 : 2 +> : ^ + +const { _a2, _b2 } = { _a2: 1, _b2: 2 }; // ok +>_a2 : number +> : ^^^^^^ +>_b2 : number +> : ^^^^^^ +>{ _a2: 1, _b2: 2 } : { _a2: number; _b2: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>_a2 : number +> : ^^^^^^ +>1 : 1 +> : ^ +>_b2 : number +> : ^^^^^^ +>2 : 2 +> : ^ + +// Functions +function unusedFunc() { } // error +>unusedFunc : () => void +> : ^^^^^^^^^^ + +function _unusedFunc() { } // ok +>_unusedFunc : () => void +> : ^^^^^^^^^^ + +const unusedArrow = () => { }; // error +>unusedArrow : () => void +> : ^^^^^^^^^^ +>() => { } : () => void +> : ^^^^^^^^^^ + +const _unusedArrow = () => { }; // ok +>_unusedArrow : () => void +> : ^^^^^^^^^^ +>() => { } : () => void +> : ^^^^^^^^^^ + +// Classes +class UnusedClass { } // error +>UnusedClass : UnusedClass +> : ^^^^^^^^^^^ + +class _UnusedClass { } // ok +>_UnusedClass : _UnusedClass +> : ^^^^^^^^^^^^ + +// Interfaces +interface UnusedInterface { } // error +interface _UnusedInterface { } // ok + +// Type aliases +type UnusedType = string; // error +>UnusedType : string +> : ^^^^^^ + +type _UnusedType = string; // ok +>_UnusedType : string +> : ^^^^^^ + +// Enums +enum UnusedEnum { A } // error +>UnusedEnum : UnusedEnum +> : ^^^^^^^^^^ +>A : UnusedEnum.A +> : ^^^^^^^^^^^^ + +enum _UnusedEnum { A } // ok +>_UnusedEnum : _UnusedEnum +> : ^^^^^^^^^^^ +>A : _UnusedEnum.A +> : ^^^^^^^^^^^^^ + +// Declarations in for loops +for (const _x of []) { } // ok +>_x : any +> : ^^^ +>[] : undefined[] +> : ^^^^^^^^^^^ + +for (const x of []) { } // error +>x : any > : ^^^ >[] : undefined[] > : ^^^^^^^^^^^ -for (const _ in []) { } ->_ : string +for (const _x in []) { } // ok +>_x : string +> : ^^^^^^ +>[] : undefined[] +> : ^^^^^^^^^^^ + +for (const x in []) { } // error +>x : string > : ^^^^^^ >[] : undefined[] > : ^^^^^^^^^^^ -namespace _ns { ->_ns : typeof _ns -> : ^^^^^^^^^^ +// Namespaces +namespace UnusedNamespace { // error +>UnusedNamespace : typeof UnusedNamespace +> : ^^^^^^^^^^^^^^^^^^^^^^ - let _; ->_ : any -> : ^^^ + export const x = 1; +>x : 1 +> : ^ +>1 : 1 +> : ^ +} +namespace _UnusedNamespace { // ok +>_UnusedNamespace : typeof _UnusedNamespace +> : ^^^^^^^^^^^^^^^^^^^^^^^ - for (const _ of []) { } ->_ : any + export const x = 1; +>x : 1 +> : ^ +>1 : 1 +> : ^ +} + +// Destructuring +const { a: unusedA } = { a: 1 }; // error +>a : any > : ^^^ ->[] : undefined[] -> : ^^^^^^^^^^^ +>unusedA : number +> : ^^^^^^ +>{ a: 1 } : { a: number; } +> : ^^^^^^^^^^^^^^ +>a : number +> : ^^^^^^ +>1 : 1 +> : ^ - for (const _ in []) { } ->_ : string +const { b: _unusedB } = { b: 2 }; // ok +>b : any +> : ^^^ +>_unusedB : number +> : ^^^^^^ +>{ b: 2 } : { b: number; } +> : ^^^^^^^^^^^^^^ +>b : number > : ^^^^^^ ->[] : undefined[] -> : ^^^^^^^^^^^ +>2 : 2 +> : ^ + +const [unusedC] = [3]; // error +>unusedC : number +> : ^^^^^^ +>[3] : [number] +> : ^^^^^^^^ +>3 : 3 +> : ^ + +const [_unusedD] = [4]; // ok +>_unusedD : number +> : ^^^^^^ +>[4] : [number] +> : ^^^^^^^^ +>4 : 4 +> : ^ + +// +// The following declarations may _not_ use an underscore to bypass @noUnusedLocals +// + +class TestClass { +>TestClass : TestClass +> : ^^^^^^^^^ + + private unusedMember = 1; // error +>unusedMember : number +> : ^^^^^^ +>1 : 1 +> : ^ + + private _unusedMember = 2; // still error +>_unusedMember : number +> : ^^^^^^ +>2 : 2 +> : ^ + + private unusedMethod() { } // error +>unusedMethod : () => void +> : ^^^^^^^^^^ + + private _unusedMethod() { } // still error +>_unusedMethod : () => void +> : ^^^^^^^^^^ } +enum TestEnum { +>TestEnum : TestEnum +> : ^^^^^^^^ + + UnusedMember = 1, // error +>UnusedMember : TestEnum.UnusedMember +> : ^^^^^^^^^^^^^^^^^^^^^ +>1 : 1 +> : ^ + + _UnusedMember = 2, // still error +>_UnusedMember : TestEnum._UnusedMember +> : ^^^^^^^^^^^^^^^^^^^^^^ +>2 : 2 +> : ^ +} + +interface TestInterface { + unusedProp: number; // error +>unusedProp : number +> : ^^^^^^ + + _unusedProp: number; // still error +>_unusedProp : number +> : ^^^^^^ +} + +const obj = { +>obj : { unusedProp: number; _unusedProp: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>{ unusedProp: 1, // error _unusedProp: 2, // still error} : { unusedProp: number; _unusedProp: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + + unusedProp: 1, // error +>unusedProp : number +> : ^^^^^^ +>1 : 1 +> : ^ + + _unusedProp: 2, // still error +>_unusedProp : number +> : ^^^^^^ +>2 : 2 +> : ^ + +}; + +export { }; diff --git a/tests/baselines/reference/unusedParametersWithUnderscore.errors.txt b/tests/baselines/reference/unusedParametersWithUnderscore.errors.txt index b99299db9b919..132d853d489b1 100644 --- a/tests/baselines/reference/unusedParametersWithUnderscore.errors.txt +++ b/tests/baselines/reference/unusedParametersWithUnderscore.errors.txt @@ -2,9 +2,9 @@ unusedParametersWithUnderscore.ts(1,12): error TS6133: 'a' is declared but its v unusedParametersWithUnderscore.ts(1,19): error TS6133: 'c' is declared but its value is never read. unusedParametersWithUnderscore.ts(1,27): error TS6133: 'd' is declared but its value is never read. unusedParametersWithUnderscore.ts(1,29): error TS6133: 'e___' is declared but its value is never read. -unusedParametersWithUnderscore.ts(5,13): error TS6198: All destructured elements are unused. -unusedParametersWithUnderscore.ts(11,16): error TS6133: 'arg' is declared but its value is never read. -unusedParametersWithUnderscore.ts(17,13): error TS6133: 'arg' is declared but its value is never read. +unusedParametersWithUnderscore.ts(9,14): error TS6198: All destructured elements are unused. +unusedParametersWithUnderscore.ts(15,16): error TS6133: 'arg' is declared but its value is never read. +unusedParametersWithUnderscore.ts(21,13): error TS6133: 'arg' is declared but its value is never read. ==== unusedParametersWithUnderscore.ts (7 errors) ==== @@ -19,9 +19,13 @@ unusedParametersWithUnderscore.ts(17,13): error TS6133: 'arg' is declared but it !!! error TS6133: 'e___' is declared but its value is never read. } - + // ok because of underscore prefix function f2({_a, __b}) { - ~~~~~~~~~ + } + + // error + function f2b({ a, b }) { + ~~~~~~~~ !!! error TS6198: All destructured elements are unused. } diff --git a/tests/baselines/reference/unusedParametersWithUnderscore.js b/tests/baselines/reference/unusedParametersWithUnderscore.js index c38ab76d9ce25..f1fd5feecb142 100644 --- a/tests/baselines/reference/unusedParametersWithUnderscore.js +++ b/tests/baselines/reference/unusedParametersWithUnderscore.js @@ -4,10 +4,14 @@ function f(a, _b, c, ___, d,e___, _f) { } - +// ok because of underscore prefix function f2({_a, __b}) { } +// error +function f2b({ a, b }) { +} + function f3([_a, ,__b]) { } @@ -27,9 +31,14 @@ var f8 = function (_) { }; //// [unusedParametersWithUnderscore.js] function f(a, _b, c, ___, d, e___, _f) { } +// ok because of underscore prefix function f2(_c) { var _a = _c._a, __b = _c.__b; } +// error +function f2b(_c) { + var a = _c.a, b = _c.b; +} function f3(_c) { var _a = _c[0], __b = _c[2]; } diff --git a/tests/baselines/reference/unusedParametersWithUnderscore.symbols b/tests/baselines/reference/unusedParametersWithUnderscore.symbols index 2d39003cf535e..3b2ad1f676aa7 100644 --- a/tests/baselines/reference/unusedParametersWithUnderscore.symbols +++ b/tests/baselines/reference/unusedParametersWithUnderscore.symbols @@ -12,41 +12,48 @@ function f(a, _b, c, ___, d,e___, _f) { >_f : Symbol(_f, Decl(unusedParametersWithUnderscore.ts, 0, 33)) } - +// ok because of underscore prefix function f2({_a, __b}) { >f2 : Symbol(f2, Decl(unusedParametersWithUnderscore.ts, 1, 1)) >_a : Symbol(_a, Decl(unusedParametersWithUnderscore.ts, 4, 13)) >__b : Symbol(__b, Decl(unusedParametersWithUnderscore.ts, 4, 16)) } +// error +function f2b({ a, b }) { +>f2b : Symbol(f2b, Decl(unusedParametersWithUnderscore.ts, 5, 1)) +>a : Symbol(a, Decl(unusedParametersWithUnderscore.ts, 8, 14)) +>b : Symbol(b, Decl(unusedParametersWithUnderscore.ts, 8, 17)) +} + function f3([_a, ,__b]) { ->f3 : Symbol(f3, Decl(unusedParametersWithUnderscore.ts, 5, 1)) ->_a : Symbol(_a, Decl(unusedParametersWithUnderscore.ts, 7, 13)) ->__b : Symbol(__b, Decl(unusedParametersWithUnderscore.ts, 7, 18)) +>f3 : Symbol(f3, Decl(unusedParametersWithUnderscore.ts, 9, 1)) +>_a : Symbol(_a, Decl(unusedParametersWithUnderscore.ts, 11, 13)) +>__b : Symbol(__b, Decl(unusedParametersWithUnderscore.ts, 11, 18)) } function f4(...arg) { ->f4 : Symbol(f4, Decl(unusedParametersWithUnderscore.ts, 8, 1)) ->arg : Symbol(arg, Decl(unusedParametersWithUnderscore.ts, 10, 12)) +>f4 : Symbol(f4, Decl(unusedParametersWithUnderscore.ts, 12, 1)) +>arg : Symbol(arg, Decl(unusedParametersWithUnderscore.ts, 14, 12)) } function f5(..._arg) { ->f5 : Symbol(f5, Decl(unusedParametersWithUnderscore.ts, 11, 1)) ->_arg : Symbol(_arg, Decl(unusedParametersWithUnderscore.ts, 13, 12)) +>f5 : Symbol(f5, Decl(unusedParametersWithUnderscore.ts, 15, 1)) +>_arg : Symbol(_arg, Decl(unusedParametersWithUnderscore.ts, 17, 12)) } function f6(arg?, _arg?) { ->f6 : Symbol(f6, Decl(unusedParametersWithUnderscore.ts, 14, 1)) ->arg : Symbol(arg, Decl(unusedParametersWithUnderscore.ts, 16, 12)) ->_arg : Symbol(_arg, Decl(unusedParametersWithUnderscore.ts, 16, 17)) +>f6 : Symbol(f6, Decl(unusedParametersWithUnderscore.ts, 18, 1)) +>arg : Symbol(arg, Decl(unusedParametersWithUnderscore.ts, 20, 12)) +>_arg : Symbol(_arg, Decl(unusedParametersWithUnderscore.ts, 20, 17)) } var f7 = _ => undefined; ->f7 : Symbol(f7, Decl(unusedParametersWithUnderscore.ts, 19, 3)) ->_ : Symbol(_, Decl(unusedParametersWithUnderscore.ts, 19, 8)) +>f7 : Symbol(f7, Decl(unusedParametersWithUnderscore.ts, 23, 3)) +>_ : Symbol(_, Decl(unusedParametersWithUnderscore.ts, 23, 8)) >undefined : Symbol(undefined) var f8 = function (_) { }; ->f8 : Symbol(f8, Decl(unusedParametersWithUnderscore.ts, 21, 3)) ->_ : Symbol(_, Decl(unusedParametersWithUnderscore.ts, 21, 19)) +>f8 : Symbol(f8, Decl(unusedParametersWithUnderscore.ts, 25, 3)) +>_ : Symbol(_, Decl(unusedParametersWithUnderscore.ts, 25, 19)) diff --git a/tests/baselines/reference/unusedParametersWithUnderscore.types b/tests/baselines/reference/unusedParametersWithUnderscore.types index 7aa5d774379a0..a75515e82da81 100644 --- a/tests/baselines/reference/unusedParametersWithUnderscore.types +++ b/tests/baselines/reference/unusedParametersWithUnderscore.types @@ -20,7 +20,7 @@ function f(a, _b, c, ___, d,e___, _f) { > : ^^^ } - +// ok because of underscore prefix function f2({_a, __b}) { >f2 : ({ _a, __b }: { _a: any; __b: any; }) => void > : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -30,6 +30,16 @@ function f2({_a, __b}) { > : ^^^ } +// error +function f2b({ a, b }) { +>f2b : ({ a, b }: { a: any; b: any; }) => void +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>a : any +> : ^^^ +>b : any +> : ^^^ +} + function f3([_a, ,__b]) { >f3 : ([_a, , __b]: [any, any, any]) => void > : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/baselines/reference/unusedTypeDeclarations.errors.txt b/tests/baselines/reference/unusedTypeDeclarations.errors.txt new file mode 100644 index 0000000000000..fd2768f62407b --- /dev/null +++ b/tests/baselines/reference/unusedTypeDeclarations.errors.txt @@ -0,0 +1,11 @@ +unusedTypeDeclarations.ts(1,6): error TS6196: 'T1' is declared but never used. + + +==== unusedTypeDeclarations.ts (1 errors) ==== + type T1 = number; // error + ~~ +!!! error TS6196: 'T1' is declared but never used. + type _T2 = number; // ok + + export {}; + \ No newline at end of file diff --git a/tests/baselines/reference/unusedTypeDeclarations.js b/tests/baselines/reference/unusedTypeDeclarations.js new file mode 100644 index 0000000000000..18f35ad63fad8 --- /dev/null +++ b/tests/baselines/reference/unusedTypeDeclarations.js @@ -0,0 +1,12 @@ +//// [tests/cases/compiler/unusedTypeDeclarations.ts] //// + +//// [unusedTypeDeclarations.ts] +type T1 = number; // error +type _T2 = number; // ok + +export {}; + + +//// [unusedTypeDeclarations.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/tests/baselines/reference/unusedTypeDeclarations.symbols b/tests/baselines/reference/unusedTypeDeclarations.symbols new file mode 100644 index 0000000000000..39a216df7a34a --- /dev/null +++ b/tests/baselines/reference/unusedTypeDeclarations.symbols @@ -0,0 +1,11 @@ +//// [tests/cases/compiler/unusedTypeDeclarations.ts] //// + +=== unusedTypeDeclarations.ts === +type T1 = number; // error +>T1 : Symbol(T1, Decl(unusedTypeDeclarations.ts, 0, 0)) + +type _T2 = number; // ok +>_T2 : Symbol(_T2, Decl(unusedTypeDeclarations.ts, 0, 17)) + +export {}; + diff --git a/tests/baselines/reference/unusedTypeDeclarations.types b/tests/baselines/reference/unusedTypeDeclarations.types new file mode 100644 index 0000000000000..57a57847a46fd --- /dev/null +++ b/tests/baselines/reference/unusedTypeDeclarations.types @@ -0,0 +1,13 @@ +//// [tests/cases/compiler/unusedTypeDeclarations.ts] //// + +=== unusedTypeDeclarations.ts === +type T1 = number; // error +>T1 : number +> : ^^^^^^ + +type _T2 = number; // ok +>_T2 : number +> : ^^^^^^ + +export {}; + diff --git a/tests/baselines/reference/unusedVariablesWithUnderscoreInBindingElement.errors.txt b/tests/baselines/reference/unusedVariablesWithUnderscoreInBindingElement.errors.txt index 24822bf1c6920..45763d754b4a8 100644 --- a/tests/baselines/reference/unusedVariablesWithUnderscoreInBindingElement.errors.txt +++ b/tests/baselines/reference/unusedVariablesWithUnderscoreInBindingElement.errors.txt @@ -132,10 +132,13 @@ unusedVariablesWithUnderscoreInBindingElement.ts(81,11): error TS6198: All destr function t7() { // error - const { _a1, _b1 } = { _a1: 1, _b1: 1 }; - ~~~~~~~~~~~~ + const { a0, b0 } = { a0: 1, b0: 1 }; + ~~~~~~~~~~ !!! error TS6198: All destructured elements are unused. + // ok + const { _a1, _b1 } = { _a1: 1, _b1: 1 }; + // ok const { a2: _a2, b2: _b2 } = { a2: 1, b2: 1 }; diff --git a/tests/baselines/reference/unusedVariablesWithUnderscoreInBindingElement.js b/tests/baselines/reference/unusedVariablesWithUnderscoreInBindingElement.js index 76347950fe9db..9c8269f80c97e 100644 --- a/tests/baselines/reference/unusedVariablesWithUnderscoreInBindingElement.js +++ b/tests/baselines/reference/unusedVariablesWithUnderscoreInBindingElement.js @@ -81,6 +81,9 @@ function t6() { function t7() { // error + const { a0, b0 } = { a0: 1, b0: 1 }; + + // ok const { _a1, _b1 } = { _a1: 1, _b1: 1 }; // ok @@ -130,9 +133,11 @@ function t6() { } function t7() { // error - var _a = { _a1: 1, _b1: 1 }, _a1 = _a._a1, _b1 = _a._b1; + var _a = { a0: 1, b0: 1 }, a0 = _a.a0, b0 = _a.b0; + // ok + var _b = { _a1: 1, _b1: 1 }, _a1 = _b._a1, _b1 = _b._b1; // ok - var _b = { a2: 1, b2: 1 }, _a2 = _b.a2, _b2 = _b.b2; + var _c = { a2: 1, b2: 1 }, _a2 = _c.a2, _b2 = _c.b2; // ok - var _c = { _a3: 1, _b3: 1 }, _ignoreA3 = _c._a3, _ignoreB3 = _c._b3; + var _d = { _a3: 1, _b3: 1 }, _ignoreA3 = _d._a3, _ignoreB3 = _d._b3; } diff --git a/tests/baselines/reference/unusedVariablesWithUnderscoreInBindingElement.symbols b/tests/baselines/reference/unusedVariablesWithUnderscoreInBindingElement.symbols index 2e3c0e99586e7..6b69de4eab245 100644 --- a/tests/baselines/reference/unusedVariablesWithUnderscoreInBindingElement.symbols +++ b/tests/baselines/reference/unusedVariablesWithUnderscoreInBindingElement.symbols @@ -254,28 +254,35 @@ function t7() { >t7 : Symbol(t7, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 76, 1)) // error + const { a0, b0 } = { a0: 1, b0: 1 }; +>a0 : Symbol(a0, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 80, 11)) +>b0 : Symbol(b0, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 80, 15)) +>a0 : Symbol(a0, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 80, 24)) +>b0 : Symbol(b0, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 80, 31)) + + // ok const { _a1, _b1 } = { _a1: 1, _b1: 1 }; ->_a1 : Symbol(_a1, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 80, 11)) ->_b1 : Symbol(_b1, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 80, 16)) ->_a1 : Symbol(_a1, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 80, 26)) ->_b1 : Symbol(_b1, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 80, 34)) +>_a1 : Symbol(_a1, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 83, 11)) +>_b1 : Symbol(_b1, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 83, 16)) +>_a1 : Symbol(_a1, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 83, 26)) +>_b1 : Symbol(_b1, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 83, 34)) // ok const { a2: _a2, b2: _b2 } = { a2: 1, b2: 1 }; ->a2 : Symbol(a2, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 83, 34)) ->_a2 : Symbol(_a2, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 83, 11)) ->b2 : Symbol(b2, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 83, 41)) ->_b2 : Symbol(_b2, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 83, 20)) ->a2 : Symbol(a2, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 83, 34)) ->b2 : Symbol(b2, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 83, 41)) +>a2 : Symbol(a2, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 86, 34)) +>_a2 : Symbol(_a2, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 86, 11)) +>b2 : Symbol(b2, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 86, 41)) +>_b2 : Symbol(_b2, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 86, 20)) +>a2 : Symbol(a2, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 86, 34)) +>b2 : Symbol(b2, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 86, 41)) // ok const { _a3: _ignoreA3, _b3: _ignoreB3 } = { _a3: 1, _b3: 1 }; ->_a3 : Symbol(_a3, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 86, 48)) ->_ignoreA3 : Symbol(_ignoreA3, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 86, 11)) ->_b3 : Symbol(_b3, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 86, 56)) ->_ignoreB3 : Symbol(_ignoreB3, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 86, 27)) ->_a3 : Symbol(_a3, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 86, 48)) ->_b3 : Symbol(_b3, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 86, 56)) +>_a3 : Symbol(_a3, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 89, 48)) +>_ignoreA3 : Symbol(_ignoreA3, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 89, 11)) +>_b3 : Symbol(_b3, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 89, 56)) +>_ignoreB3 : Symbol(_ignoreB3, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 89, 27)) +>_a3 : Symbol(_a3, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 89, 48)) +>_b3 : Symbol(_b3, Decl(unusedVariablesWithUnderscoreInBindingElement.ts, 89, 56)) } diff --git a/tests/baselines/reference/unusedVariablesWithUnderscoreInBindingElement.types b/tests/baselines/reference/unusedVariablesWithUnderscoreInBindingElement.types index eebef095a18ca..c1aaf71e3d0a3 100644 --- a/tests/baselines/reference/unusedVariablesWithUnderscoreInBindingElement.types +++ b/tests/baselines/reference/unusedVariablesWithUnderscoreInBindingElement.types @@ -577,6 +577,23 @@ function t7() { > : ^^^^^^^^^^ // error + const { a0, b0 } = { a0: 1, b0: 1 }; +>a0 : number +> : ^^^^^^ +>b0 : number +> : ^^^^^^ +>{ a0: 1, b0: 1 } : { a0: number; b0: number; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>a0 : number +> : ^^^^^^ +>1 : 1 +> : ^ +>b0 : number +> : ^^^^^^ +>1 : 1 +> : ^ + + // ok const { _a1, _b1 } = { _a1: 1, _b1: 1 }; >_a1 : number > : ^^^^^^ diff --git a/tests/cases/compiler/noUnusedLocals_types.ts b/tests/cases/compiler/noUnusedLocals_types.ts new file mode 100644 index 0000000000000..06a095420a497 --- /dev/null +++ b/tests/cases/compiler/noUnusedLocals_types.ts @@ -0,0 +1,18 @@ +// @noUnusedLocals: true +// Test specifically for type declarations with underscore prefix + +// These should all produce errors (no underscore) +type UnusedType1 = string; +interface UnusedInterface1 { x: number; } +class UnusedClass1 { } + +// These should NOT produce errors (underscore prefix) +type _UnusedType2 = string; +interface _UnusedInterface2 { x: number; } +class _UnusedClass2 { } + +// Mixed usage - only the one without underscore should error +type UsedInOther = number; +type _Helper = UsedInOther; // _Helper is not an error, but it uses UsedInOther + +export {}; \ No newline at end of file diff --git a/tests/cases/compiler/unusedLocalsStartingWithUnderscore.ts b/tests/cases/compiler/unusedLocalsStartingWithUnderscore.ts index 431d4fd15d8cb..d76a6b032e250 100644 --- a/tests/cases/compiler/unusedLocalsStartingWithUnderscore.ts +++ b/tests/cases/compiler/unusedLocalsStartingWithUnderscore.ts @@ -1,15 +1,86 @@ // @noUnusedLocals:true -// @Filename: /a.ts -import * as _ from "./a"; +// Variables +const unusedVar = 1; // error +const _unusedVar = 2; // ok -for (const _ of []) { } +let unusedLet = 3; // error +let _unusedLet = 4; // ok -for (const _ in []) { } +var unusedVar2 = 5; // error +var _unusedVar2 = 6; // ok -namespace _ns { - let _; - for (const _ of []) { } +const { a1, _b1 } = { a1: 1, _b1: 2 }; // error on a1 +const { _a2, _b2 } = { _a2: 1, _b2: 2 }; // ok - for (const _ in []) { } +// Functions +function unusedFunc() { } // error +function _unusedFunc() { } // ok + +const unusedArrow = () => { }; // error +const _unusedArrow = () => { }; // ok + +// Classes +class UnusedClass { } // error +class _UnusedClass { } // ok + +// Interfaces +interface UnusedInterface { } // error +interface _UnusedInterface { } // ok + +// Type aliases +type UnusedType = string; // error +type _UnusedType = string; // ok + +// Enums +enum UnusedEnum { A } // error +enum _UnusedEnum { A } // ok + +// Declarations in for loops +for (const _x of []) { } // ok +for (const x of []) { } // error +for (const _x in []) { } // ok +for (const x in []) { } // error + +// Namespaces +namespace UnusedNamespace { // error + export const x = 1; +} +namespace _UnusedNamespace { // ok + export const x = 1; } + +// Destructuring +const { a: unusedA } = { a: 1 }; // error +const { b: _unusedB } = { b: 2 }; // ok +const [unusedC] = [3]; // error +const [_unusedD] = [4]; // ok + +// +// The following declarations may _not_ use an underscore to bypass @noUnusedLocals +// + +class TestClass { + private unusedMember = 1; // error + private _unusedMember = 2; // still error + + private unusedMethod() { } // error + private _unusedMethod() { } // still error +} + +enum TestEnum { + UnusedMember = 1, // error + _UnusedMember = 2, // still error +} + +interface TestInterface { + unusedProp: number; // error + _unusedProp: number; // still error +} + +const obj = { + unusedProp: 1, // error + _unusedProp: 2, // still error +}; + +export { }; \ No newline at end of file diff --git a/tests/cases/compiler/unusedParametersWithUnderscore.ts b/tests/cases/compiler/unusedParametersWithUnderscore.ts index e7382e5c2af2c..b98ed9f562172 100644 --- a/tests/cases/compiler/unusedParametersWithUnderscore.ts +++ b/tests/cases/compiler/unusedParametersWithUnderscore.ts @@ -4,10 +4,14 @@ function f(a, _b, c, ___, d,e___, _f) { } - +// ok because of underscore prefix function f2({_a, __b}) { } +// error +function f2b({ a, b }) { +} + function f3([_a, ,__b]) { } diff --git a/tests/cases/compiler/unusedTypeDeclarations.ts b/tests/cases/compiler/unusedTypeDeclarations.ts new file mode 100644 index 0000000000000..364b458323a25 --- /dev/null +++ b/tests/cases/compiler/unusedTypeDeclarations.ts @@ -0,0 +1,6 @@ +// @noUnusedLocals: true + +type T1 = number; // error +type _T2 = number; // ok + +export {}; diff --git a/tests/cases/compiler/unusedVariablesWithUnderscoreInBindingElement.ts b/tests/cases/compiler/unusedVariablesWithUnderscoreInBindingElement.ts index 23b732d51edb9..75d257dfe2f20 100644 --- a/tests/cases/compiler/unusedVariablesWithUnderscoreInBindingElement.ts +++ b/tests/cases/compiler/unusedVariablesWithUnderscoreInBindingElement.ts @@ -80,6 +80,9 @@ function t6() { function t7() { // error + const { a0, b0 } = { a0: 1, b0: 1 }; + + // ok const { _a1, _b1 } = { _a1: 1, _b1: 1 }; // ok