pzavolinsky / ts-unused-exports

ts-unused-exports finds unused exported symbols in your Typescript project
MIT License
749 stars 49 forks source link

Question: what about "exported for testing" #2

Open danvk opened 7 years ago

danvk commented 7 years ago

Suppose I have this setup:

// src/main.ts
export function unused() {}
export function helper() { ... }  // exported for testing
export default function main() {
  helper();
}
// src/index.ts
import main from './main';
main();
// test/main_test.ts
import { helper } from './main';
// test helper()

Every exported symbol in this project is imported by another module, so ts-unused-exports won't report any problems. But unused is dead code, since it's only called from a test.

It would be nice if there were some way of capturing this. Running

ts-unused-exports tsconfig.json src/*.ts

comes close, except that it will also report that helper is unused.

Some ideas:

Thanks for writing this tool!

pzavolinsky commented 7 years ago

Hi @danvk, thanks for your comment!

In your example, wouldn't running:

ts-unused-exports tsconfig.json

have the desired results? (i.e. only report unused as unused)

Cheers!

danvk commented 7 years ago

@pzavolinsky what are you imagining is in tsconfig.json?

I tried it with this:

{
  "files": [
     "src/index.ts"
   ]
}

and got no errors:

$ ts-unused-exports tsconfig.json
0 modules with unused exports

Here's the full example:

$ for x in $(find . -type f); do echo "\n$x\n------"; cat $x; done
./src/index.ts
------
// src/index.ts
import main from './main';
main();
./src/main.ts
------
// src/main.ts
export function unused() {}
export function helper() {

}  // exported for testing
export default function main() {
  helper();
}

./test/main_test.ts
------
// test/main_test.ts
import { helper } from '../src/main';
// test helper()

./tsconfig.json
------
{
  "files": [
     "src/index.ts"
   ]
}
pzavolinsky commented 7 years ago

what are you imagining is in tsconfig.json?

My bad, I though you had a full tsconfig.json like this one:

{
  "files": [
     "src/index.ts",
     "src/main.ts",
     "test/main_test.ts"
   ]
}

In your case, I guess running the following should work:

ts-unused-exports tsconfig.json  $(find -name '*.ts')
1 module with unused exports
src/main: unused, main

Note that in src/main.ts the name for the default export (i.e. main) is not being used and that is why it gets reported (maybe this is a bug, I'm on the fence). Fixing that:

export default function() {
  helper();
}

You get the expected unused:

ts-unused-exports tsconfig.json  $(find -name '*.ts')
1 module with unused exports
src/main: unused

Cheers!

mrseanryan commented 5 years ago

@danvk in case it helps:

Support a comment (// exported for testing) or decorator (@ExportedForTesting) which suppresses output for a symbol.

You can now use comment flags to ignore exports:

// ts-unused-exports:disable-next-line
export function helper() { ... }  // exported for testing
mrseanryan commented 4 years ago

Closing (question answered)

mrseanryan commented 4 years ago

@danvk opening this again, as we got a similar question just now #98 .

RE:

Have a flag which filters out un-imported exports which are referenced within their own module

This is similar to #30

So:

note: having separate options could be useful, since is safer to implement, and we don't know the full range of projects that are using this tool note: There are many conventions for test file names... That option could cover typical cases (.spec.ts. .test.ts)

A second option could allow match via regex:

--ignoreImportsFrom=/.(test|spec)/.

(related) with all these options, adding a config file could help at this point!

mrseanryan commented 4 years ago

update: PR #107 allows ignoring test files, or other files.

TODO:

Have a flag which filters out un-imported exports which are referenced within their own module

mrseanryan commented 4 years ago

Update: version 6 has new options to control what files are included:

Add options to ignore imports from certain files: 
--ignoreFiles=(regex) 
--ignoreProductionFiles
--ignoreTestFiles

So for example to find exports only imported in tests, then option ignoreTestFiles can be used.

Depending on your test files and framework, you might want to specify a regex on the filename, in which can use option ignireFiles