Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork2.8k
Description
Before You File a Proposal Please Confirm You Have Done The Following...
- I havesearched for related issues and found none that match my proposal.
- I have searched thecurrent rule list and found no rules that match my proposal.
- I haveread the FAQ and my problem is not listed.
My proposal is suitable for this project
- I believe my proposal would be useful to the broader TypeScript community (meaning it is not a niche proposal).
Link to the rule's documentation
https://typescript-eslint.io/rules/no-unused-vars/
Description
Currently allno-unused-vars
errors are not fixable. This is for good reasons, eg:
- side-effects are possible nearly everywhere in JS and it's impossible for us to know if an expression has a side-effect
- unused variables are a common part of the developer workflow and many people use autofix-on-save in their IDE -- so a fixer would cause "soon to be used" variables from being auto-deleted accidentally (an obviously frustrating DevX!)
With that being said there is one subset of unused variables which aregenerally safe to autofix -- imported names. These are generally safe to fix because:
- the vast, vast, vast majority of modules do not have top-level side-effects
- most bundlers and minifiers run on the assumption that modules DO NOT have side-effects!
- imports are mostly managed by the IDE (eg an IDE will auto-add import on usage of imported thing) and so removing a "soon to be used" import generally is low-impact from DevX.
There's evidence that the community wants this -- for exampleeslint-plugin-unused-imports
exists and is pretty widely used (they have ~8.4% of our weekly downloads). This plugin introduces two rules -- both are just monkey-patched extension rules on top of ourno-unused-vars
implementation where one rule only reports on variables and the other only reports on imports and provides a fixer.
My proposal is the following:
- add a new option, say
enableAutofixRemoval: { imports: boolean }
with defaultenableAutofixRemoval: { imports: false }
(i.e. disable the autofixer by default). - build an autofixer for imported names that does the following:
- if the unused name is a namespace import, remove the entire import declaration.
- if the unused name is a default import:
- if there are no used named imports in the declaration, remove the entire import declaration.
- if there are used named imports in the declaration, just remove the unused default import.
- if the unused name is a named import:
- if there are no other used names in the declaration, remove the entire import declaration.
- if there are used names in the declaration, just remove the unused named import.
- if
enableAutofixRemoval.imports === true
- then set the fixer from (2) as anauto-fixer
- else set the fixer from (2) as asuggestion fixer
Additional Info
Namespace:
import*asUnusedfrom'foo';import*asUsedfrom'foo';export{Used};
autofixes to:
import*asUsedfrom'foo';export{Used};
Default:
importUnused1from'foo';importUnused2,{Used}from'foo';export{Used};
autofixes to:
import{Used}from'foo';export{Used};
Named:
import{Unused1}from'foo';importUsed1,{Unused2}from'foo';import{Unused3,Used2}from'foo';importUsed3,{Unused4,Used4}from'foo';export{Used1,Used2,Used3,Used4};
autofixes to:
importUsed1from'foo';import{Used2}from'foo';importUsed3,{Used4}from'foo';export{Used1,Used2,Used3,Used4};