pzavolinsky / ts-unused-exports

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

Argument --allowUnusedTypes does not apply to type re-exports #180

Closed kachkaev closed 3 years ago

kachkaev commented 3 years ago

First things first: fantastic tool 😍 I tried it in a large project yesterday and found so much dead code!

I’d like to report one little issue that I’ve noticed. When I add --allowUnusedTypes, I still get reports for types that have been re-exported via export type { Foo } from "./foo";. Here is an MWE:

  1. Init the project:

    mkdir ts-unused-exports-false-positives
    cd ts-unused-exports-false-positives
    yarn init --yes
    yarn add -D typescript@4.1.2 ts-unused-exports@7.0.0
    cat <<EOF >tsconfig.json
    {}
    EOF
  2. Create TypeScript files

    cat <<EOF >index.ts
    import { fn1 } from "./fn1";
    import { fn2 } from "./fn2";
    
    console.log(fn1({ x: 1, y: 2 }), fn2({ a: 3, b: 4 }));
    EOF
    cat <<EOF >fn1.ts
    export interface Fn1Input {
      x: number;
      y: number;
    }
    
    export const fn1 = (input: Fn1Input): number => input.x + input.y;
    EOF
    cat <<EOF >fn2/fn2.ts
    export interface Fn2Input {
      a: number;
      b: number;
    }
    
    export const fn2 = (input: Fn2Input): number => input.a - input.b;
    EOF
    cat <<EOF >fn2/index.ts
    export { fn2 } from "./fn2";
    export type { Fn2Input } from "./fn2"; // πŸ‘ˆ πŸ‘€
    EOF
  3. Run ts-unused-exports without --allowUnusedTypes

    yarn ts-unused-exports tsconfig.json

    Output:

    2 modules with unused exports
    /path/to/ts-unused-exports-false-positives/fn1.ts: Fn1Input
    /path/to/ts-unused-exports-false-positives/fn2/index.ts: Fn2Input
    error Command failed with exit code 1.

    All works as expected.

  4. Run ts-unused-exports with --allowUnusedTypes

    yarn ts-unused-exports tsconfig.json --allowUnusedTypes

    Output:

    1 module with unused exports
    /path/to/ts-unused-exports-false-positives/fn2/index.ts: Fn2Input
    error Command failed with exit code 1.

    Expected output:

    0 modules with unused exports

In the real scenario, I have functions with React components and interfaces with component props. Re-exports are needed because some components are complex and are therefore put into sub-folders. Having export type as an extra line is necessary when the component itself is a default export (it’s not possible to export * from "./fn2" in this case).

Happy to help with finding a solution, if needed. Thanks again for the tool πŸ™Œ

mrseanryan commented 3 years ago

Hi @kachkaev thanks for reporting.

I think this could be solved via https://github.com/pzavolinsky/ts-unused-exports/issues/30

mrseanryan commented 3 years ago

TODO:

@kachkaev if you have the time, it would be great to have your contribution!

kachkaev commented 3 years ago

Hi @mrseanryan! I think that the proposed ignoreLocallyUsed option in #30 is not doing quite the same thing. To me, reporting export const a which could be const a is a valid feedback, while --allowUnusedTypes + export type ... is a false positive.

I’m not familiar with the architecture of ts-unused-exports at this point, so I wonder if detecting symbols that stick out via export type is at all feasible. From my observations, --allowUnusedTypes works well already and the only false positives are when there is export type { X } from "./someFile".

Happy to try contributing with the unit tests.

kachkaev commented 3 years ago

I added some broken tests in #181

UPD: Oh wow looks like I fixed it. Neat codebase folks πŸ‘

mrseanryan commented 3 years ago

Thank you @kachkaev for contributing πŸ‘

mrseanryan commented 3 years ago

@pzavolinsky we can release this as a patch :)