From b3165107cb3dc091ed0ca66980702c86f5be1d8c Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Mon, 17 Jun 2024 02:01:20 +0300 Subject: [PATCH 1/3] feat(58561): allow leading underscore for types to bypass noUnusedLocals warning --- src/compiler/checker.ts | 8 ++++++++ .../reference/unusedTypeDeclarations.errors.txt | 11 +++++++++++ tests/baselines/reference/unusedTypeDeclarations.js | 12 ++++++++++++ .../reference/unusedTypeDeclarations.symbols | 11 +++++++++++ .../reference/unusedTypeDeclarations.types | 13 +++++++++++++ tests/cases/compiler/unusedTypeDeclarations.ts | 6 ++++++ 6 files changed, 61 insertions(+) create mode 100644 tests/baselines/reference/unusedTypeDeclarations.errors.txt create mode 100644 tests/baselines/reference/unusedTypeDeclarations.js create mode 100644 tests/baselines/reference/unusedTypeDeclarations.symbols create mode 100644 tests/baselines/reference/unusedTypeDeclarations.types create mode 100644 tests/cases/compiler/unusedTypeDeclarations.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 75be36474222f..b644e21ddb8d4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -44390,6 +44390,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } } + function isTypeParameterUnused(typeParameter: TypeParameterDeclaration): boolean { return !(getMergedSymbol(typeParameter.symbol).isReferenced! & SymbolFlags.TypeParameter) && !isIdentifierThatStartsWithUnderscore(typeParameter.name); } @@ -44410,6 +44411,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function isValidUnusedLocalDeclaration(declaration: Declaration): boolean { + if (isTypeAliasDeclaration(declaration)) { + /** + * ignore starts with underscore names _ + * type _T = number; + */ + return isIdentifierThatStartsWithUnderscore(declaration.name); + } if (isBindingElement(declaration)) { if (isObjectBindingPattern(declaration.parent)) { /** 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/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 {}; From 57a256c42e45f5e324843b20308862d1fa2dde36 Mon Sep 17 00:00:00 2001 From: Jon Shea Date: Fri, 22 Aug 2025 14:20:28 -0400 Subject: [PATCH 2/3] Baseline `isTypeParameterUnused` with new tests This commit introduces new tests against the baseline (ie, unchanged from before this PR) `isTypeParameterUnused` implementation. --- src/compiler/checker.ts | 8 - .../reference/noUnusedLocals_types.errors.txt | 41 +++ .../reference/noUnusedLocals_types.js | 35 +++ .../reference/noUnusedLocals_types.symbols | 36 +++ .../reference/noUnusedLocals_types.types | 41 +++ ...sedLocalsStartingWithUnderscore.errors.txt | 197 +++++++++++- .../unusedLocalsStartingWithUnderscore.js | 179 +++++++++-- ...unusedLocalsStartingWithUnderscore.symbols | 178 ++++++++++- .../unusedLocalsStartingWithUnderscore.types | 297 ++++++++++++++++-- .../unusedTypeDeclarations.errors.txt | 5 +- tests/cases/compiler/noUnusedLocals_types.ts | 18 ++ .../unusedLocalsStartingWithUnderscore.ts | 87 ++++- 12 files changed, 1032 insertions(+), 90 deletions(-) create mode 100644 tests/baselines/reference/noUnusedLocals_types.errors.txt create mode 100644 tests/baselines/reference/noUnusedLocals_types.js create mode 100644 tests/baselines/reference/noUnusedLocals_types.symbols create mode 100644 tests/baselines/reference/noUnusedLocals_types.types create mode 100644 tests/cases/compiler/noUnusedLocals_types.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b644e21ddb8d4..75be36474222f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -44390,7 +44390,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } } - function isTypeParameterUnused(typeParameter: TypeParameterDeclaration): boolean { return !(getMergedSymbol(typeParameter.symbol).isReferenced! & SymbolFlags.TypeParameter) && !isIdentifierThatStartsWithUnderscore(typeParameter.name); } @@ -44411,13 +44410,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function isValidUnusedLocalDeclaration(declaration: Declaration): boolean { - if (isTypeAliasDeclaration(declaration)) { - /** - * ignore starts with underscore names _ - * type _T = number; - */ - return isIdentifierThatStartsWithUnderscore(declaration.name); - } if (isBindingElement(declaration)) { if (isObjectBindingPattern(declaration.parent)) { /** diff --git a/tests/baselines/reference/noUnusedLocals_types.errors.txt b/tests/baselines/reference/noUnusedLocals_types.errors.txt new file mode 100644 index 0000000000000..75dab9b943fc6 --- /dev/null +++ b/tests/baselines/reference/noUnusedLocals_types.errors.txt @@ -0,0 +1,41 @@ +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(9,6): error TS6196: '_UnusedType2' is declared but never used. +noUnusedLocals_types.ts(10,11): error TS6196: '_UnusedInterface2' is declared but never used. +noUnusedLocals_types.ts(11,7): error TS6196: '_UnusedClass2' is declared but never used. +noUnusedLocals_types.ts(15,6): error TS6196: '_Helper' is declared but never used. + + +==== noUnusedLocals_types.ts (7 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; + ~~~~~~~~~~~~ +!!! error TS6196: '_UnusedType2' is declared but never used. + interface _UnusedInterface2 { x: number; } + ~~~~~~~~~~~~~~~~~ +!!! error TS6196: '_UnusedInterface2' is declared but never used. + class _UnusedClass2 { } + ~~~~~~~~~~~~~ +!!! error TS6196: '_UnusedClass2' is declared but never used. + + // Mixed usage - only the one without underscore should error + type UsedInOther = number; + type _Helper = UsedInOther; // _Helper is not an error, but it uses UsedInOther + ~~~~~~~ +!!! error TS6196: '_Helper' is declared but never used. + + 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..b4e3020673298 100644 --- a/tests/baselines/reference/unusedLocalsStartingWithUnderscore.errors.txt +++ b/tests/baselines/reference/unusedLocalsStartingWithUnderscore.errors.txt @@ -1,22 +1,189 @@ -/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(3,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(6,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(9,5): error TS6133: '_unusedVar2' is declared but its value is never read. +unusedLocalsStartingWithUnderscore.ts(11,7): error TS6198: All destructured elements are unused. +unusedLocalsStartingWithUnderscore.ts(12,7): error TS6198: All destructured elements are unused. +unusedLocalsStartingWithUnderscore.ts(15,10): error TS6133: 'unusedFunc' is declared but its value is never read. +unusedLocalsStartingWithUnderscore.ts(16,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(19,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(23,7): error TS6196: '_UnusedClass' is declared but never used. +unusedLocalsStartingWithUnderscore.ts(26,11): error TS6196: 'UnusedInterface' is declared but never used. +unusedLocalsStartingWithUnderscore.ts(27,11): error TS6196: '_UnusedInterface' is declared but never used. +unusedLocalsStartingWithUnderscore.ts(30,6): error TS6196: 'UnusedType' is declared but never used. +unusedLocalsStartingWithUnderscore.ts(31,6): error TS6196: '_UnusedType' is declared but never used. +unusedLocalsStartingWithUnderscore.ts(34,6): error TS6196: 'UnusedEnum' is declared but never used. +unusedLocalsStartingWithUnderscore.ts(35,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(47,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 (34 errors) ==== + // Variables + const unusedVar = 1; // error + ~~~~~~~~~ +!!! error TS6133: 'unusedVar' is declared but its value is never read. + const _unusedVar = 2; // ok + ~~~~~~~~~~ +!!! error TS6133: '_unusedVar' is declared but its value is never read. - for (const _ of []) { } + let unusedLet = 3; // error + ~~~~~~~~~ +!!! error TS6133: 'unusedLet' is declared but its value is never read. + let _unusedLet = 4; // ok + ~~~~~~~~~~ +!!! error TS6133: '_unusedLet' is declared but its value is never read. - for (const _ in []) { } + var unusedVar2 = 5; // error + ~~~~~~~~~~ +!!! error TS6133: 'unusedVar2' is declared but its value is never read. + var _unusedVar2 = 6; // ok + ~~~~~~~~~~~ +!!! error TS6133: '_unusedVar2' is declared but its value is never read. - 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 TS6198: All destructured elements are unused. + const { _a2, _b2 } = { _a2: 1, _b2: 2 }; // ok + ~~~~~~~~~~~~ +!!! error TS6198: All destructured elements are unused. - for (const _ in []) { } + // Functions + function unusedFunc() { } // error + ~~~~~~~~~~ +!!! error TS6133: 'unusedFunc' is declared but its value is never read. + function _unusedFunc() { } // ok + ~~~~~~~~~~~ +!!! error TS6133: '_unusedFunc' is declared but its value is never read. + + const unusedArrow = () => { }; // error + ~~~~~~~~~~~ +!!! error TS6133: 'unusedArrow' is declared but its value is never read. + const _unusedArrow = () => { }; // ok + ~~~~~~~~~~~~ +!!! error TS6133: '_unusedArrow' is declared but its value is never read. + + // Classes + class UnusedClass { } // error + ~~~~~~~~~~~ +!!! error TS6196: 'UnusedClass' is declared but never used. + class _UnusedClass { } // ok + ~~~~~~~~~~~~ +!!! error TS6196: '_UnusedClass' is declared but never used. + + // Interfaces + interface UnusedInterface { } // error + ~~~~~~~~~~~~~~~ +!!! error TS6196: 'UnusedInterface' is declared but never used. + interface _UnusedInterface { } // ok + ~~~~~~~~~~~~~~~~ +!!! error TS6196: '_UnusedInterface' is declared but never used. + + // Type aliases + type UnusedType = string; // error + ~~~~~~~~~~ +!!! error TS6196: 'UnusedType' is declared but never used. + type _UnusedType = string; // ok + ~~~~~~~~~~~ +!!! error TS6196: '_UnusedType' is declared but never used. + + // Enums + enum UnusedEnum { A } // error + ~~~~~~~~~~ +!!! error TS6196: 'UnusedEnum' is declared but never used. + enum _UnusedEnum { A } // ok + ~~~~~~~~~~~ +!!! error TS6196: '_UnusedEnum' is declared but never used. + + // 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 + ~~~~~~~~~~~~~~~~ +!!! error TS6133: '_UnusedNamespace' is declared but its value is never read. + 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/unusedTypeDeclarations.errors.txt b/tests/baselines/reference/unusedTypeDeclarations.errors.txt index fd2768f62407b..11431bb8a6ddd 100644 --- a/tests/baselines/reference/unusedTypeDeclarations.errors.txt +++ b/tests/baselines/reference/unusedTypeDeclarations.errors.txt @@ -1,11 +1,14 @@ unusedTypeDeclarations.ts(1,6): error TS6196: 'T1' is declared but never used. +unusedTypeDeclarations.ts(2,6): error TS6196: '_T2' is declared but never used. -==== unusedTypeDeclarations.ts (1 errors) ==== +==== unusedTypeDeclarations.ts (2 errors) ==== type T1 = number; // error ~~ !!! error TS6196: 'T1' is declared but never used. type _T2 = number; // ok + ~~~ +!!! error TS6196: '_T2' is declared but never used. export {}; \ No newline at end of file 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 From fdd4051e00cca393407d2b2a7181b8bfcf453149 Mon Sep 17 00:00:00 2001 From: Jon Shea Date: Fri, 22 Aug 2025 16:49:03 -0400 Subject: [PATCH 3/3] Allow underscore prefix to bypass noUnusedLocals warning This PR continues [Allow leading underscore for types...](https://github.com/microsoft/TypeScript/pull/58884/), taking into account feedback from https://github.com/microsoft/TypeScript/pull/58884/files#r1643108204. The initial commit on this PR is original work by @a-tarasyuk. The second commit enhances the test suite and reverts the change to checker.ts to get a new baseline on the test suite for easier comparison with the changes. The third commit changes checker.ts to allow any unused local if it is prefixed with an underscore. This has the effect of newly allowing the following unused declarations: ```ts // Variables were previously allowed only in destructuring and for-loops const _unusedVar = 2; let _unusedLet = 4; var _unusedVar2 = 6; // These two no longer raise // error TS6198: All destructured elements are unused const { _a, _b } = { _a: 1, _b: 1 }; function f2({_a, _b}) function _unusedFunc() { } const _unusedArrow = () => { }; class _UnusedClass { } interface _UnusedInterface { } type _UnusedType = string; enum _UnusedEnum { A } namespace _UnusedNamespace { ... } ``` As far as I can tell, enum members and properties are not checked in the checkUnusedLocalsAndParameters function, and we do not need to special-case them. Closes https://github.com/microsoft/TypeScript/issues/58561 --- src/compiler/checker.ts | 18 +------- .../reference/noUnusedLocals_types.errors.txt | 14 +------ ...sedLocalsStartingWithUnderscore.errors.txt | 41 ++----------------- .../unusedParametersWithUnderscore.errors.txt | 14 ++++--- .../unusedParametersWithUnderscore.js | 11 ++++- .../unusedParametersWithUnderscore.symbols | 37 ++++++++++------- .../unusedParametersWithUnderscore.types | 12 +++++- .../unusedTypeDeclarations.errors.txt | 5 +-- ...sWithUnderscoreInBindingElement.errors.txt | 7 +++- ...VariablesWithUnderscoreInBindingElement.js | 11 +++-- ...blesWithUnderscoreInBindingElement.symbols | 39 ++++++++++-------- ...iablesWithUnderscoreInBindingElement.types | 17 ++++++++ .../unusedParametersWithUnderscore.ts | 6 ++- ...VariablesWithUnderscoreInBindingElement.ts | 3 ++ 14 files changed, 121 insertions(+), 114 deletions(-) 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 index 75dab9b943fc6..e2aefdbe8d642 100644 --- a/tests/baselines/reference/noUnusedLocals_types.errors.txt +++ b/tests/baselines/reference/noUnusedLocals_types.errors.txt @@ -1,13 +1,9 @@ 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(9,6): error TS6196: '_UnusedType2' is declared but never used. -noUnusedLocals_types.ts(10,11): error TS6196: '_UnusedInterface2' is declared but never used. -noUnusedLocals_types.ts(11,7): error TS6196: '_UnusedClass2' is declared but never used. -noUnusedLocals_types.ts(15,6): error TS6196: '_Helper' is declared but never used. -==== noUnusedLocals_types.ts (7 errors) ==== +==== noUnusedLocals_types.ts (3 errors) ==== // Test specifically for type declarations with underscore prefix // These should all produce errors (no underscore) @@ -23,19 +19,11 @@ noUnusedLocals_types.ts(15,6): error TS6196: '_Helper' is declared but never use // These should NOT produce errors (underscore prefix) type _UnusedType2 = string; - ~~~~~~~~~~~~ -!!! error TS6196: '_UnusedType2' is declared but never used. interface _UnusedInterface2 { x: number; } - ~~~~~~~~~~~~~~~~~ -!!! error TS6196: '_UnusedInterface2' is declared but never used. class _UnusedClass2 { } - ~~~~~~~~~~~~~ -!!! error TS6196: '_UnusedClass2' is declared but never used. // Mixed usage - only the one without underscore should error type UsedInOther = number; type _Helper = UsedInOther; // _Helper is not an error, but it uses UsedInOther - ~~~~~~~ -!!! error TS6196: '_Helper' is declared but never used. export {}; \ No newline at end of file diff --git a/tests/baselines/reference/unusedLocalsStartingWithUnderscore.errors.txt b/tests/baselines/reference/unusedLocalsStartingWithUnderscore.errors.txt index b4e3020673298..52464b16fe632 100644 --- a/tests/baselines/reference/unusedLocalsStartingWithUnderscore.errors.txt +++ b/tests/baselines/reference/unusedLocalsStartingWithUnderscore.errors.txt @@ -1,27 +1,16 @@ unusedLocalsStartingWithUnderscore.ts(2,7): error TS6133: 'unusedVar' is declared but its value is never read. -unusedLocalsStartingWithUnderscore.ts(3,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(6,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(9,5): error TS6133: '_unusedVar2' is declared but its value is never read. -unusedLocalsStartingWithUnderscore.ts(11,7): error TS6198: All destructured elements are unused. -unusedLocalsStartingWithUnderscore.ts(12,7): error TS6198: All destructured elements are unused. +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(16,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(19,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(23,7): error TS6196: '_UnusedClass' is declared but never used. unusedLocalsStartingWithUnderscore.ts(26,11): error TS6196: 'UnusedInterface' is declared but never used. -unusedLocalsStartingWithUnderscore.ts(27,11): error TS6196: '_UnusedInterface' is declared but never used. unusedLocalsStartingWithUnderscore.ts(30,6): error TS6196: 'UnusedType' is declared but never used. -unusedLocalsStartingWithUnderscore.ts(31,6): error TS6196: '_UnusedType' is declared but never used. unusedLocalsStartingWithUnderscore.ts(34,6): error TS6196: 'UnusedEnum' is declared but never used. -unusedLocalsStartingWithUnderscore.ts(35,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(47,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. @@ -34,82 +23,62 @@ unusedLocalsStartingWithUnderscore.ts(74,11): error TS6196: 'TestInterface' is d unusedLocalsStartingWithUnderscore.ts(79,7): error TS6133: 'obj' is declared but its value is never read. -==== unusedLocalsStartingWithUnderscore.ts (34 errors) ==== +==== unusedLocalsStartingWithUnderscore.ts (23 errors) ==== // Variables const unusedVar = 1; // error ~~~~~~~~~ !!! error TS6133: 'unusedVar' is declared but its value is never read. const _unusedVar = 2; // ok - ~~~~~~~~~~ -!!! error TS6133: '_unusedVar' is declared but its value is never read. let unusedLet = 3; // error ~~~~~~~~~ !!! error TS6133: 'unusedLet' is declared but its value is never read. let _unusedLet = 4; // ok - ~~~~~~~~~~ -!!! error TS6133: '_unusedLet' is declared but its value is never read. var unusedVar2 = 5; // error ~~~~~~~~~~ !!! error TS6133: 'unusedVar2' is declared but its value is never read. var _unusedVar2 = 6; // ok - ~~~~~~~~~~~ -!!! error TS6133: '_unusedVar2' is declared but its value is never read. const { a1, _b1 } = { a1: 1, _b1: 2 }; // error on a1 - ~~~~~~~~~~~ -!!! error TS6198: All destructured elements are unused. + ~~ +!!! error TS6133: 'a1' is declared but its value is never read. const { _a2, _b2 } = { _a2: 1, _b2: 2 }; // ok - ~~~~~~~~~~~~ -!!! error TS6198: All destructured elements are unused. // Functions function unusedFunc() { } // error ~~~~~~~~~~ !!! error TS6133: 'unusedFunc' is declared but its value is never read. function _unusedFunc() { } // ok - ~~~~~~~~~~~ -!!! error TS6133: '_unusedFunc' is declared but its value is never read. const unusedArrow = () => { }; // error ~~~~~~~~~~~ !!! error TS6133: 'unusedArrow' is declared but its value is never read. const _unusedArrow = () => { }; // ok - ~~~~~~~~~~~~ -!!! error TS6133: '_unusedArrow' is declared but its value is never read. // Classes class UnusedClass { } // error ~~~~~~~~~~~ !!! error TS6196: 'UnusedClass' is declared but never used. class _UnusedClass { } // ok - ~~~~~~~~~~~~ -!!! error TS6196: '_UnusedClass' is declared but never used. // Interfaces interface UnusedInterface { } // error ~~~~~~~~~~~~~~~ !!! error TS6196: 'UnusedInterface' is declared but never used. interface _UnusedInterface { } // ok - ~~~~~~~~~~~~~~~~ -!!! error TS6196: '_UnusedInterface' is declared but never used. // Type aliases type UnusedType = string; // error ~~~~~~~~~~ !!! error TS6196: 'UnusedType' is declared but never used. type _UnusedType = string; // ok - ~~~~~~~~~~~ -!!! error TS6196: '_UnusedType' is declared but never used. // Enums enum UnusedEnum { A } // error ~~~~~~~~~~ !!! error TS6196: 'UnusedEnum' is declared but never used. enum _UnusedEnum { A } // ok - ~~~~~~~~~~~ -!!! error TS6196: '_UnusedEnum' is declared but never used. // Declarations in for loops for (const _x of []) { } // ok @@ -128,8 +97,6 @@ unusedLocalsStartingWithUnderscore.ts(79,7): error TS6133: 'obj' is declared but export const x = 1; } namespace _UnusedNamespace { // ok - ~~~~~~~~~~~~~~~~ -!!! error TS6133: '_UnusedNamespace' is declared but its value is never read. export const x = 1; } 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 index 11431bb8a6ddd..fd2768f62407b 100644 --- a/tests/baselines/reference/unusedTypeDeclarations.errors.txt +++ b/tests/baselines/reference/unusedTypeDeclarations.errors.txt @@ -1,14 +1,11 @@ unusedTypeDeclarations.ts(1,6): error TS6196: 'T1' is declared but never used. -unusedTypeDeclarations.ts(2,6): error TS6196: '_T2' is declared but never used. -==== unusedTypeDeclarations.ts (2 errors) ==== +==== unusedTypeDeclarations.ts (1 errors) ==== type T1 = number; // error ~~ !!! error TS6196: 'T1' is declared but never used. type _T2 = number; // ok - ~~~ -!!! error TS6196: '_T2' is declared but never used. export {}; \ No newline at end of file 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/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/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