Is there a reason why tree shaking algorithms don't prune unused class members? My IDE can tell me when a method is unused, it seems odd that the tree shaker can't.
Because you can write `this[anything()]()` and it's impossible to analyze it. IDE false negative will not do anything bad, but treeshaker false negative will introduce a bug, so they have to be conservative.
That's not entirely true. Tree-shaking algorithms could have a “noDynamicAccess” option that errors on such use (only viable for applications, not libraries). Alternatively, the algorithm could be integrated with the TypeScript compiler API to allow dynamic access in some cases (e.g. where the `anything` function in your example only returns a “string literal” constant type or a union thereof, instead of the `string` type).
Does that work for all class members? I think I've only ever seen that on private members, though I don't know whether that's because it's so much easier to check whether a private member is used or because an unused public member isn't an issue for eg a library.
This feels like an issue that reduces down to the Halting Problem, though. Halting is a function that could be made a member of a class, so if you could tell whether that method is used or not then you could tell whether the program will halt or not. I think it's one of those things that feels like it should be fairly easy, and it's really really not.
Comparing this to the halting problem isn't really meaningful here because even if you could make a full mapping (which yours isn't), you can prove that a rather large subset of programs halt, which is good enough for a tree shaker.
I don't need to be able to eliminate every single unused function in every situation, but if I can prove that certain functions are unused then I can delete just those functions. We're already doing this regularly with standalone functions, so my question is just why this isn't done with class members.
Ah, I see your question now. Prototypes maybe? I’m not nearly a good enough JS dev to have a reasonable guess at that specifically.
Being able to access class members using square bracket syntax with a variable also seems like it would make it really difficult to prove that something isn’t used. I’m thinking something unhinged like using parameters to build a string named after a class member and then accessing it that way.
Dunno, I would be curious if someone has a definitive answer as well.
It requires flow analysis, which is really hard to get right. I don't think there's a tree-shaking library that uses the TypeScript compiler API for static analysis purposes. Maybe because it would be slow?
edit: The creator of Terser is working on flow analysis for his new minifier, according to him[1].