Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

ts-unused-exports

pzavolinsky511.7kMIT11.0.1TypeScript support: included

ts-unused-exports finds unused exported symbols in your Typescript project

typescript, tslint, unused exports, dead code

readme

ts-unused-exports

ts-unused-exports finds unused exported symbols in your Typescript project.

Build Status Coveralls

npm Package NPM Downloads

License: MIT

ko-fi

Installation

npm install --save-dev ts-unused-exports

or, to install globally:

npm install -g ts-unused-exports

Usage

./node_modules/.bin/ts-unused-exports path/to/tsconfig.json [file1.ts ...] [options]

or, if installed globally:

ts-unused-exports path/to/tsconfig.json [file1.ts ...] [options]

Usage Options

Option name Description Example
allowUnusedEnums Allow unused enums. --allowUnusedEnums
allowUnusedTypes Allow unused type or interface. --allowUnusedTypes
excludeDeclarationFiles Exclude .d.ts files when looking for unused exports. --excludeDeclarationFiles
excludePathsFromReport Exclude files from the output that match the given path segments or regex. The path segments or regexes are separated with a semi-colon. --excludePathsFromReport=math;utils
exitWithCount Set the process exit code to be the count of files that have unused exports. --exitWithCount
exitWithUnusedTypesCount Set the process exit code to be the total count of unused exported types. --exitWithUnusedTypesCount
findCompletelyUnusedFiles Find all completely unused files (where all exports are unused). --findCompletelyUnusedFiles
ignoreFiles Ignore files with filenames that match the given regex. Use this to exclude groups of files - for example test files and their utilities. --ignoreFiles=.*spec
ignoreLocallyUsed Exports which are used in the same file they are defined in won't be reported as unused. Note that this may have an impact on performance in larger codebases. --ignoreLocallyUsed
ignoreProductionFiles Only scan test files (so ignore non-test 'production' files). --ignoreProductionFiles
ignoreTestFiles Only scan production files (ignore all test files, like spec.ts(x) or test.ts(x) or TestUtils.ts). Use this to detect production code that is only used in tests (so is dead code). Note: this will NOT detect unused exports in test code - for that, you can run ts-unused-exports separately with the --ignoreProductionFiles option. --ignoreTestFiles
maxIssues Return successfully for up to a given number of modules with unused exports. --maxIssues=7
searchNamespaces Enable searching for unused exports within namespaces. Note: this can affect performance on large codebases. --searchNamespaces
showLineNumber Show the line number and column of the unused export. --showLineNumber
silent Don't write on stdout on success. --silent

Note that if ts-unused-exports is called without files, the files will be read from the tsconfig's files or include key which must be present. If called with files, then those file paths should be relative to the tsconfig.json, just like you would specify them in your tsconfig's files key.

ts-unused-exports also resolves path aliases specified in tsconfig's paths object.

As of version 7.0.0 the TypeScript compiler is a peer dependency of ts-unused-exports. This means that if the TypeScript compiler is not already in the same spot as ts-unused-exports, you have to install it yourself (e.g. with npm i -D typescript).

Usage as a library

Usage as a library - From TypeScript (was built with ES5 + commonjs)

import { analyzeTsConfig } from 'ts-unused-exports';
const result = analyzeTsConfig('path/to/tsconfig.json');
// or const result = analyzeTsConfig('path/to/tsconfig.json', ['file1.ts']);
// or const result = analyzeTsConfig('path/to/tsconfig.json', ['file1.ts', '--excludePathsFromReport=math']);

// result : { [index:string] : ExportNameAndLocation[] }
// where the keys are file paths and the values are a structure descibing unused symbols:
// interface ExportNameAndLocation {
//   exportName: string;
//   location: LocationInFile;
// }

For an example see ./example/library-usage-via-TypeScript/.

Usage as a library - From JavaScript

From JavaScript - depending on your environment, you may need to navigate to reach the analyzeTsConfig() function.

import { analyzeTsConfig } from "ts-unused-exports";
const result = analyzeTsConfig.default('path/to/tsconfig.json');

For an example see ./example/library-usage-via-JavaScript/.

Why should I use this?

If you've ever used tslint's no-unused-variable rule you already known how awesome it is. What this rule does is detect code in your modules that is not being used so that you can remove it.

For example, say that you refactored your math.ts module so that you no longer use add1:

function add1(x: number) {
  return x + 1;
} // warning here

export default (x: number) => x + 1;

When run, tslint will complain that add1 is no longer in use.

Unfortunately, if your symbols are exported, tslint does not complain anymore. Effectively exporting a symbol anchors the symbol so that, even if nobody uses it, it will not be marked as dead code.

If you've ever found yourself mid-refactor fixing a particularly fiendish function only to realize later that nobody really uses it you know exactly what I mean.

ts-unused-exports fills this cross-module gap by complaining about exported symbols that no-one cares about.

In this sense, ts-unused-exports does not replace tslint but rather complements it by helping you detect unnecessary exports. Once those are fixed, tslint's no-unused-variable rule will kick in and tell you which code you can safely remove.

Example

There is a (very silly) example in the example/simple directory.

If you want to run it you can:

git clone https://github.com/pzavolinsky/ts-unused-exports
cd ts-unused-exports
./bin/ts-unused-exports example/simple/tsconfig.json
# or: node ./bin/ts-unused-exports example/simple/tsconfig.json
# or: node bin\ts-unused-exports example\simple\tsconfig.json

The output should be:

2 modules with unused exports
/home/stuff/src/github/ts-unused-exports/example/simple/math.ts: add1
/home/stuff/src/github/ts-unused-exports/example/simple/unused.ts: unused

Exit Code

Normally, the exit code follows the convention used by eslint:

  • 0 = Linting was successful and there are no linting errors.
  • 1 = Linting was successful and there is at least one linting error.
  • 2 = Linting was unsuccessful due to bad arguments or an internal error.

If the option --maxIssues=n is used, then linting is considered successful, if at most n issues are found.

If the option --exitWithCount is used, then the exit status will equal the number of offending modules:

echo $?
# or: echo %ERRORLEVEL%
2

Similarly, the option --exitWithUnusedTypesCount means that the exit status will equal the number of offending types.

Specifying which TypeScript files to check

If not using files or include inside your tsconfig (e.g. using webpack with ts-loader), you can explicitly specify the files to check in the command line:

./bin/ts-unused-exports example/simple/tsconfig.json app.ts math.ts

or, in a more generic way:

./bin/ts-unused-exports example/simple/tsconfig.json $(cd example/simple; find -name '*.ts')

You can use comment flags to ignore exports:

// ts-unused-exports:disable-next-line
export function add2(x: number) {
  return x + 2;
}

Tooling

eslint plugins

ts-unused-exports can also be executed via this eslint plugin by Gajus Kuizinas.

Changelog (Release History)

To see what has changed in each version, please see our CHANGELOG.md.

Contributing

ts-unused-exports is maintained by volunteers, working in their free time. If you'd like to help out, please see CONTRIBUTING.md.

ts-unused-exports was created by Patricio Zavolinsky. Improvements were contributed by the open source community.

Licence: MIT

This project is licensed under the MIT License - see the LICENSE file for details

changelog

[11.0.1] - 25 Nov 2024

Changed

  • updated examples and README to match the changes in version 11.0.0

[11.0.0] - 25 Nov 2024

Changed

  • BREAKING CHANGE: The default export (API entry point) has been changed to be compatible with esm module (should also work with cjs)
  • BREAKING CHANGE: The results (API) structure has been changed:
    • OLD:
      const result = {
      "filePath1": { /* ... */ },
      "filePath2": { /* ... */ },
      /* ... */
      unusedFiles: { /* ... */ },
      };
    • NEW:
      const result = {
      unusedExports: {
        "filePath1": { /* ... */ },
        "filePath2": { /* ... */ },
        /* ... */
      },
      unusedFiles: [ "filePath1", "filePath2", /*"..."*/ ]
      };
  • fix: The scope of --ignoreTestFiles has been reduced, to make it less likely to exclude non-test files
  • (internal) built using Node v20.13.1

[10.1.0] - 24 May 2024

Changed

  • fix: --ignorefiles was ignoring file extensions when matching - #296
  • fix: --ignoreLocallyUsed had some false positives. Detail: was incorrectly excluding when parent is variable or function declaration - #300

[10.0.1] - 4 Sept 2023

Changed

  • fix: an extra semicolon in the setting --excludePathsFromReport should not break the filtering. #297.

[10.0.0] - 9 Aug 2023

Changed

  • the setting excludePathsFromReport now supports regex - #293
  • handle import statements that contain '.ts' or '.tsx' extensions - #281

[9.0.5] - 24 Jun 2023

Added

  • Add --ignoreLocallyUsed flag which means that exports which are used in the same file they are defined in won't be reported as unused

[9.0.4] - 12 Feb 2023

Changed

  • Improve handling of transitive imports like 'a -> b -> c' especially where 'export *' is used - #216
  • Improve output format when the unused item involves an 'export *'.

[9.0.3] - 5 Feb 2023

Changed

  • Fix for import from index file via a custom path - avoids false positives on index files - #266. Now tested with more cases such as import from "foo" OR import from "foo/index" with various file extensions supported.
  • ts-unused-exports npm package: Updated the version in package-lock.json
  • Fixed the example using ts-unused-exports as a library via TypeScript

[9.0.2] - 15 Jan 2023

Added

  • Added better examples of how to use as a library, via TypeScript or JavaScript. No code was changed.

[9.0.1] - 4 Jan 2023

Changed

  • Fix for index files that end with .js or .cjs or .mjs.

[9.0.0] - 26 Dec 2022

Added

  • Allow for importing of 'x.js' files as opposed to simply 'x'. This aims towards supporting es6 and higher modules as opposed to CommonJS.

  • Add option --findCompletelyUnusedFiles to check for completely unused files

[8.0.5] - 10 Dec 2022

Changed

  • Add support for running from a directory not the 'project' directory that contains tsconfig.json. (Issue #248)

[8.0.2] - 5 Dec 2022

Changed

  • Fix handling of files ending with 'index.ts': do not always report as containing unused exports. Do allow ignoring via ignoreFile regex.

[8.0.0] - 14 Feb 2022

Changed

  • Fix: Add support for 'extends' in tsconfig.json (Issue #102, #200)
  • (Internal) Using absolute paths which is less ambiguous. Delegating tsconfig.json parsing to TypeScript.

[7.0.3] - 25 Feb 2021

Changed

  • Package metadata related to funding and financial support, no functional or implementation changes.

[7.0.2] - 23 Feb 2021

Changed

  • Fix false positives on Windows machines when using absolute paths (baseUrl) or aliases (paths).

[7.0.1] - 18 Jan 2021`

Changed

  • Updated the chalk dependency (no change in behavior)
  • (Internal) Updated the dev dependencies, involving lot of small changes adding parentheses to lambda parameters.
  • Fix --allowUnusedTypes not applying to type re-exports (Issue #180)
  • Fix --allowUnusedEnums not applying to enum re-exports

[7.0.0] - 11 Nov 2020

Changed

  • BREAKING CHANGE: Makes TypeScript a peer dependency (Issue #159)
    Migration path: If you already have a version of the TypeScript compiler installed in the same spot as ts-unused-exports no migration steps are necessary (it will work out of the box). Otherwise you'll have to install the TypeScript compiler there yourself (e.g. with npm i -D typescript).
  • Fixed false positive with path aliases and sub-folders (Issue #154)
  • Improved support for export * as (Issue #160)

[6.3.0] - 11 Nov 2020

Added

  • Add option 'exitWithUnusedTypesCount' to exit with a number indicating the total count of unused types. (Issue #172)
  • Add option 'allowUnusedEnums' to skip unused enums. (Issue #165). Also fixes bug where option 'allowUnusedTypes' also turned on option 'excludeDeclarationFiles'.

Changed

  • if 0 issues (0 modules with unused exports) then use the default color. (Issue #164)
  • Add an option to stop writing to stdout on success: --silent

[6.2.4] - 14 Sep 2020

Changed

  • Dependency: update node-fetch.

[6.2.3] - 27 Aug 2020

Changed

  • Fix: false positives if importing from a d.ts file, and tsconfig is set to use aliases (paths).

[6.2.2] - 25 Aug 2020

Changed

  • Fix: when dynamic import has curly braces around parameter
  • Fix: false positives if importing from a d.ts file, and tsconfig is set to use either absolute paths (baseUrl) or aliases (paths).

[6.2.1] - 1 Jun 2020

Changed

  • Fix: Dynamically import with destructuring and less whitespace
  • Fix: Dynamically import to a promise (Issue #139)
  • Fix: Dynamically import with lambda inside div (Issue #140)
  • (Internal) Add dynamic import tests involving ternary operator

[6.2.0] - 11 May 2020

Changed

  • (Internal) Using TypeScript 3.8

Added

  • Handle dynamic imports within a TSX div or fragment
  • Add basic support for export * as namespace.

[6.1.2] - 1 Apr 2020

Changed

  • Fix to make the exports analyzer more robust

[6.1.1] - 22 Mar 2020

Changed

  • Fix to support destructured exports with renaming, like 'export const { a: a2 }'
  • Fix: Dynamic import with destructuring and renaming
  • Fix: Do not classify other lambdas as using a dynamic import
  • Fix: Include methods when searching for dynamic imports

[6.1.0] - 4 Mar 2020

Added

  • Add an option to allow maximum number of issues: --maxIssues

Changed

  • Fix to support destructuerd exports like 'export const { a, b }'
  • Handle dynamic imports that use dereferencing

[6.0.0] - 24 Jan 2020

Added

  • Add options to ignore imports from certain files: --ignoreFiles, --ignoreProductionFiles, --ignoreTestFiles

Changed

  • BREAKING CHANGE: renamed the option --ignorePaths to be --excludePathsFromReport

[5.5.0] - 20 Jan 2020

Added

  • Add option --allowUnusedTypes to skip unused types or interfaces.

[5.4.0] - 19 Jan 2020

Added

  • Support exports destructured from array (issue #31)

[5.3.0] - 04 Jan 2020

Added

  • Handle exports from within a namespace. Disabled by default, unless option --searchNamespaces is given. Note: this can affect performance on large codebases.

[5.2.0] - 23 Dec 2019

Changed

  • (Internal) Update dependency TypeScript to 3.7.3
  • (Internal) Simplify some logic, using the new optional chaining operator (?.)
  • (Internal) Increase code coverage and simplify code (baseUrl defaults to '.')

[5.1.0] - 26 Nov 2019

Added

  • Detect dynamic imports, to avoid false reports of unused exports
  • Handle the alias from 'export default as', to avoid false positives.

Changed

  • (Internal) Update dependencies (except for TypeScript)

[5.0.0] - 22 Nov 2019

Added

  • Include .d.ts files when searching for unused exports. This can be disabled via the --excludeDeclarationFiles option.

[4.0.0] - 07 Nov 2019

Changed

  • use eslint-style exit code (0 = no issues, 1 = unused exports found, 2 = exception occurred)
  • (Internal) add code coverage via nyc
  • (Internal) code coverage and linting are included in npm test
  • (Internal) add more unit tests, increasing the code coverage
  • Limit max exit code when --exitWithCount option is used (max is 127, a signed byte)
  • (Internal) add badges including: code coverage, npm package version, license, dependency status.

[3.0.3] - 30 Oct 2019

Changed

  • (Internal) Add eslint with default rules (via typescript-eslint)
  • (Internal) Fix all the linting issues

[3.0.2] - 28 Oct 2019

Changed

  • (Internal) Replaced jasmine tests with cucumber tests
  • Fix handling of import from index files, like "." or "./index.ts"

[3.0.1] - 28 Oct 2019

Changed

  • Fix bug introduced by --showLineNumber option, where analysis throws error on more complex projects.

[3.0.0] - 27 Oct 2019

Changed

  • Updated TypeScript dependency to 3.6.4

[2.2.0] - 27 Oct 2019

Added

  • If the option --showLineNumber is given, then output 1 line per unused export, with the location in the file (line number, column)

Changed

  • Fix the --ignorePaths option (it was incorrectly filtering the parsed files, instead of filtering the output)

[2.1.0] - 20 Oct 2019

Added

  • Add comment flag to ignore some exports
  • Add tsconfig paths aliases support
  • Remove recursive imports check (performance on big projects)
  • Use tsconfig 'paths' to resolve import paths
  • Print full paths in console, with color highlighting
  • Add cmd line option to ignore results from some file paths

Changed

  • By default, the process exit code will be 0 unless there was a critical error (bad arguments or a missing file)
  • If the option --exitWithCount is given, then return the count of files that have unused exports