You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
importShapefrom"./Shape";classCircleextendsShape{constructor(){super();// FIXME: description should show as unused in VSCode, as it does in WebStorm.this.description='A circle shape';}// FIXME: circleLog should show as unused in VSCode, as it does in WebStorm.circleLog(){// NOTE: both VSCode and WebStorm have detected an unused variable.constnum=2;// NOTE: colorLog is being used, so no unused code errors in Shape.js file.super.colorLog();}}// FIXME: export should show as unused in VSCode, as it does in WebStorm.exportdefaultCircle;
We currently assume that exported members form a public API and therefore are always used. We could try to detect that a certain set of files are an API entrypoints, and then mark unused internal exports. Not sure if there are any issue already tracking this
Reacted by Alan.He, Tomasz Galkowski, OldStarchy, Daan, René Zschoch and aceArt-GmbH
Update: much faster after adding dummy getProjectVersion implementation assuming the project doesn't change during execution.
My naive solution below. It's pretty slow even though it should only run a full compilation once. I'll post updates if I improve it.
constfs=require("fs");constts=require("typescript");constpath=require("path");// Copied from https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API#incremental-build-support-using-the-language-servicesfunctiongetLanguageService(rootFileNames,options){constfiles={};// initialize the list of filesrootFileNames.forEach(fileName=>{files[fileName]={version: 0};});// Create the language service host to allow the LS to communicate with the hostconstservicesHost={getScriptFileNames: ()=>rootFileNames,getScriptVersion: fileName=>files[fileName]&&files[fileName].version.toString(),getScriptSnapshot: fileName=>{if(!fs.existsSync(fileName)){returnundefined;}returnts.ScriptSnapshot.fromString(fs.readFileSync(fileName).toString());},getCurrentDirectory: ()=>process.cwd(),getCompilationSettings: ()=>options,getDefaultLibFileName: options=>ts.getDefaultLibFilePath(options),getProjectVersion: ()=>1,fileExists: ts.sys.fileExists,readFile: ts.sys.readFile,readDirectory: ts.sys.readDirectory,};// Create the language service filesconstservices=ts.createLanguageService(servicesHost,ts.createDocumentRegistry());returnservices;}consttsconfigPath="tsconfig.gen.json";constbasePath=path.resolve(path.dirname(tsconfigPath));constparseJsonResult=ts.parseConfigFileTextToJson(tsconfigPath,fs.readFileSync(tsconfigPath,{encoding: "utf8"}));consttsConfig=ts.parseJsonConfigFileContent(parseJsonResult.config,ts.sys,basePath);constservices=getLanguageService(tsConfig.fileNames,tsConfig.options);// For each non-typings filetsConfig.fileNames.filter(f=>!f.endsWith(".d.ts")).forEach(file=>{constsource=ts.createSourceFile(file,fs.readFileSync(file,{encoding: "utf8"}));ts.forEachChild(source,node=>{if(ts.isClassDeclaration(node)){// For each class membernode.members.forEach(member=>{// If member is marked as public or protected and not a constructorif((ts.getCombinedModifierFlags(member)&ts.ModifierFlags.Public||ts.getCombinedModifierFlags(member)&ts.ModifierFlags.Protected)&&member.kind!==ts.SyntaxKind.Constructor){constreferences=services.findReferences(file,member.name.pos+1);// Fail if every reference is a definition and not in a typings fileif(references.every(reference=>reference.references.length===1&&reference.references[0].isDefinition&&!reference.definition.fileName.endsWith(".d.ts"))){console.error(`File: ${file} , Member: ${member.name.text}`);}}});}});});
Reacted by Ayoub Gdah
Reacted by Ayoub Gdah
Reacted by Bogdan Vitoc, AlCalzone, EGComputerworks, Ayoub Gdah, 0xAuwtch, Yves Van Goethem, Jose Pradenas Navarro, Andrii Oriekhov, Yuriy and Artur Gawlik
I would like this because using top-level exports, and destructuring imports can clutter your files quite a lot. E.g. I would like to make a Util class I can use the default import on, without worrying about forgetting to delete unused functions a year down the road.
Or would namespaces be a solution to this problem? (does unused code detection work on namespaces?)
Reacted by Alan.He, SigmaOutdoors, Joseph Chambers, Memas Deligeorgakis, Tomasz Galkowski, Tony Gentilcore, Carsten Dietzel, Daan, Adam Žingor and René Zschoch
In my opinion it is very clear that the desired behavior is to do what webstorm already does.
I'm torn between whether this should be a feature of the language itself or a feature of a separate tool, but in the end, all I really care about is that VSCode can tell me which public methods are unused by the rest of the code (for library code that's not consumed within the same codebase, it is also a good indicator of spotting untested methods)
So it's 2024 and I had to touch Typescript for the first time today and within a few minutes wished for there to be a visual indicator for an unused method and landed here, in this Issue from 2019. Am I understanding correctly that even after 5 years this is still not possible and people are still being recommended Webstorm instead?
You are absolutely correct. This is a shame!
VS Code is such a nice IDE, but there are some features which are just better in Webstorm...
I'm thinking of switching, since in quite some issues there is no movement.
Lol I just switched from Webstorm to VSCode because of issues in Webstorm... I guess the neighbor's grass is always greener.
I noticed that vscode has a setting named "typescript.referencesCodeLens.enabled" that is able to detect number of "references" for public methods as well (I assume this feature is provided by typescript). I wonder if it's possible to enable to configure a rule like "if this is 0, it should show as unused"
I'm not sure if this "algorithm" addresses concerns for false negative/positive pointed out by Ryan Cavanaugh (@RyanCavanaugh), but I assume that many users (including myself) will prefer to use it nontheless, and perhaps it would be a good enough reason to stay in VS Code rather than moving to Webstorm.
For now I'm trying to use this feature as a workaround, so at least I have some visual indication when something is not used (=not referenced)
Author of Knip here. Apart from the discussion what should be built-in to TS or what IDE is better, I just wanted to give a little heads up as to what Knip currently does (not), which might be of relief today:
Knip finds unused files, exports and dependencies.
From the OP code sample: it should find unused (default) export and it finds unused class members as well
Knip is not a generic dead code finder, but built around a module and dependency graph to link up imports and exports. So it does a lot around that, and is less concerned about unused variables/members within a file. So when it comes to public APIs and exports and members of those exports, Knip might be able to help, also with settings such as includeEntryExports and a production mode.
It's complementary to e.g. ESLint, tsc and tree-shaking.
There are no IDE plugins, there's only a CLI atm. Various reporters, and running the default one has clickable links to files with issues including position. But not the red squigglies yet afaic.
By the way, recently I've been looking into Unused exported type & interface members. Unfortunately this will likely not be generally released, mostly for being too limited in scope, potential maintenance hell, etc. That said, if a codebase has similar structures as the examples in the provisional docs, it might be interesting to try it out. Who knows.
Happy to discuss any of this, but please file such feedback and issues specific to Knip in that repo or Discord.
Reacted by Reece Daniels, René Zschoch, Josh Pike, Andrii Oriekhov and Uladzimir Kalinets
I was not satisfied with this answer and all the tools out there seem to ignore anything "public" so I made a thing to help. See the gist here. I think it could be useful to you but let me know in the comments of the gist if you think it could be better.
Caveats:
It looks at Angular components and assumes if it is not used in the local html file (of the same name) then it is "unused".
There are some edgecases accounted for.
It ignores HostListener functions and all the ng* lifecycle hooks.
It also ignores some types that pretty much always are "unused" in the local html like EventEmitter.
It only looks at components with existing html files. It will not look at services or other file types.
Activity
mjbvz commentedon Jan 7, 2019
We currently assume that exported members form a public API and therefore are always used. We could try to detect that a certain set of files are an API entrypoints, and then mark unused internal exports. Not sure if there are any issue already tracking this
[-]Expand unused detection[/-][+]Show unused public properties and methods[/+]auchenberg commentedon Feb 23, 2019
Customer demand for this feature mentioned in https://dev.to/mokkapps/why-i-switched-from-visual-studio-code-to-jetbrains-webstorm-939.
zpdDG4gta8XKpMCd commentedon Mar 1, 2019
what about exported but unused
fatihturgut commentedon Sep 18, 2019
is there any news about this issue?
jp7837 commentedon Oct 16, 2019
Update: much faster after adding dummy
getProjectVersionimplementation assuming the project doesn't change during execution.My naive solution below.
It's pretty slow even though it should only run a full compilation once. I'll post updates if I improve it.alanhe421 commentedon Mar 11, 2020
I was wondering if we could use custom rules to detect and fix this kind of problem
Bogidon commentedon Mar 25, 2020
I would like this because using top-level exports, and destructuring imports can clutter your files quite a lot. E.g. I would like to make a
Utilclass I can use the default import on, without worrying about forgetting to delete unused functions a year down the road.Or would namespaces be a solution to this problem? (does unused code detection work on namespaces?)
iulianraduat commentedon Mar 25, 2020
I am also interested to remove the kind of dead code mentioned by zpdDG4gta8XKpMCd .
Maybe Patricio Zavolinsky (pzavolinsky), creator of https://www.npmjs.com/package/ts-unused-exports, can help the Visual Code team to implement it?
28 remaining items
Papooch commentedon May 14, 2024
In my opinion it is very clear that the desired behavior is to do what webstorm already does.
I'm torn between whether this should be a feature of the language itself or a feature of a separate tool, but in the end, all I really care about is that VSCode can tell me which public methods are unused by the rest of the code (for library code that's not consumed within the same codebase, it is also a good indicator of spotting untested methods)
RyanCavanaugh commentedon May 14, 2024
I don't know what Webstorm's algorithm is or what its false positives/negatives are. Can you go into more detail on it?
sixtyfive commentedon Jun 6, 2024
So it's 2024 and I had to touch Typescript for the first time today and within a few minutes wished for there to be a visual indicator for an unused method and landed here, in this Issue from 2019. Am I understanding correctly that even after 5 years this is still not possible and people are still being recommended Webstorm instead?
dave0688 commentedon Jun 6, 2024
You are absolutely correct. This is a shame!
VS Code is such a nice IDE, but there are some features which are just better in Webstorm...
I'm thinking of switching, since in quite some issues there is no movement.
ShacharHarshuv commentedon Mar 10, 2025
Lol I just switched from Webstorm to VSCode because of issues in Webstorm... I guess the neighbor's grass is always greener.
I noticed that vscode has a setting named "typescript.referencesCodeLens.enabled" that is able to detect number of "references" for public methods as well (I assume this feature is provided by typescript). I wonder if it's possible to enable to configure a rule like "if this is 0, it should show as unused"
I'm not sure if this "algorithm" addresses concerns for false negative/positive pointed out by Ryan Cavanaugh (@RyanCavanaugh), but I assume that many users (including myself) will prefer to use it nontheless, and perhaps it would be a good enough reason to stay in VS Code rather than moving to Webstorm.
For now I'm trying to use this feature as a workaround, so at least I have some visual indication when something is not used (=not referenced)
chore: add knip to portalicious
chore: add knip to portalicious
webpro commentedon Mar 23, 2025
Author of Knip here. Apart from the discussion what should be built-in to TS or what IDE is better, I just wanted to give a little heads up as to what Knip currently does (not), which might be of relief today:
tscand tree-shaking.By the way, recently I've been looking into Unused exported type & interface members. Unfortunately this will likely not be generally released, mostly for being too limited in scope, potential maintenance hell, etc. That said, if a codebase has similar structures as the examples in the provisional docs, it might be interesting to try it out. Who knows.
Happy to discuss any of this, but please file such feedback and issues specific to Knip in that repo or Discord.
chore: add knip to portalicious
chore: add knip to portalicious
chore: add knip to portalicious
chore: add knip to portalicious
chore: add knip to portalicious
chore: check for dead code in portalicious with knip (#6638)
triadzack commentedon Jul 16, 2025
I was not satisfied with this answer and all the tools out there seem to ignore anything "public" so I made a thing to help. See the gist here. I think it could be useful to you but let me know in the comments of the gist if you think it could be better.
Caveats:
It looks at Angular components and assumes if it is not used in the local html file (of the same name) then it is "unused".
There are some edgecases accounted for.
It ignores HostListener functions and all the ng* lifecycle hooks.
It also ignores some types that pretty much always are "unused" in the local html like EventEmitter.
It only looks at components with existing html files. It will not look at services or other file types.