type-coverage: Measuring any Usage in TypeScript
A CLI tool to check type coverage for typescript code
At a glance
- What is it?
- type-coverage is a command-line analyzer that measures how many TypeScript identifiers have a non-any type. It is aimed at teams migrating JavaScript to TypeScript, tightening existing types, or enforcing a coverage threshold in CI.
- Who is it for?
- Teams adopting TypeScript incrementally or tightening loose types should evaluate type-coverage, while projects wanting a full static analysis report or a general-purpose linting framework should not treat it as a replacement. Before adoption, verify how your TypeScript version and compiler options affect the result, then test `--strict`, `--detail`, and the threshold you intend to enforce.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 9 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What type-coverage Measures
type-coverage solves a narrow but useful problem: it estimates how much of a TypeScript codebase has escaped explicit type checking. The README defines type coverage as the count of identifiers whose type is not `any`, divided by the total count of identifiers. It presents the resulting percentage as a metric where the higher rate is better.
The intended users are teams doing progressive migration. A JavaScript codebase being moved to TypeScript can use the result to track whether typed code is replacing untyped code. A TypeScript codebase with permissive annotations can use the same metric to identify remaining weak types. A team can also run the command in CI to prevent accidental `any` from entering the project.
This is different from asking whether a program has no type errors. The metric focuses on identifier types, not general runtime correctness, API design, test coverage, or code quality. A project can type-check successfully while still containing several `any` values, and a high coverage result does not establish that the types are precise. It is better understood as a migration and policy metric.
How the TypeScript Analysis Works
The CLI accepts a `tsconfig.json` path, analyzes the project, and reports uncovered identifiers according to its type-coverage rules. The ordinary mode treats identifiers whose type is `any` as uncovered. Detail mode is intended to show where those identifiers occur, while `--show-relative-path` changes the displayed path format.
The tool has several switches for defining what counts. `--strict` makes `any` inside type arguments count as uncovered, including forms such as `any[]`, `ReadonlyArray<any>`, `Promise<any>`, and `Foo<number, any>`. It also treats type assertions as uncovered, except for documented exclusions such as `as const`, `<const>foo`, and assertions powered by `isTypeAssignableTo`. The README warns that future minor releases may add stricter checks in this mode, which can reduce the reported coverage rate.
Several options tune the accounting rather than the TypeScript compiler. `--ignore-catch` addresses the fact that catch variables can block a 100 percent result. `--ignore-nested`, `--ignore-as-assertion`, `--ignore-type-assertion`, `--ignore-non-null-assertion`, `--ignore-object`, and `--ignore-empty-type` exclude particular forms from the uncovered count. `--report-unused-ignore` checks whether documented ignore-line directives are no longer needed, and strict mode enables that report by default.
Installation and a First Coverage Run
The README gives a Yarn global installation command. It installs both the `type-coverage` package and the `typescript` package because the tool analyzes TypeScript code. The documentation does not describe a separate local installation procedure or a version pin for this command.
Install the command with Yarn globally. This makes `type-coverage` available from the shell used for the subsequent command.
yarn global add type-coverage typescriptFrom the directory containing the TypeScript project, run the CLI without arguments. The README says that this checks the current project, using the default TypeScript project location.
type-coverageFor a project outside the current directory, pass the project configuration path with the documented flag. The value below is copied from the README and points to the repository's `tsconfig.json`.
type-coverage --project tsconfig.jsonA useful first follow-up is `--detail`, which asks the CLI to show details about uncovered identifiers. `--show-relative-path` can be added when the output should use relative paths. The README does not define the exact output format, so the first run should be treated as a configuration check rather than a guaranteed report layout.
CI Thresholds and Package Configuration
The main policy feature is the ability to fail when coverage falls below a required value. `--at-least` supplies a minimum rate, and `--is` requires an exact rate. These are useful when the threshold is part of a repository's acceptance rules. `--update` can change the relevant `typeCoverage` value in `package.json`, while `--update-if-higher` updates the configured value only when the current result is higher.
Configuration can live in `package.json` instead of requiring every flag on the command line. The repository's root `package.json` contains a private workspace configuration with an `atLeast` value of `99.52`. The README documents package configuration keys such as `project`, `strict`, `cache`, `detail`, `ignoreCatch`, `ignoreFiles`, and `suppressError`. The root `package.json` confirms that `typeCoverage` is the configuration section and that `atLeast` is numeric.
This arrangement is relevant to CI because a command can be checked against a repository-owned threshold instead of requiring each developer to remember a numeric policy. However, the README does not provide a complete CI workflow, so it does not establish which runner or shell command should be used. The integration boundary is the CLI exit behavior and the documented `typeCoverage` configuration.
Caching and Incremental Migration
For repeated runs, `--cache` enables reuse of type-check results. The documentation says unchanged and independent files are saved and reused from a `.type-coverage` directory. `--cache-directory` selects another directory for that data. This design is relevant to long-running migrations because it avoids repeating work for files that did not change.
The tool also supports narrower file selection. Supplying one or more files after `--` checks only those files, which the README describes as useful with tools such as `lint-staged`. `--ignore-files` excludes files by path pattern, with repeated arguments shown in the documentation. `--not-only-in-cwd` includes results outside the current working directory.
These controls make the tool usable in both repository-wide checks and focused local checks. They also introduce an operational choice: cached results need a suitable directory, while restricted file lists may not represent the complete project. The README does not explain cache invalidation details, concurrency behavior, or the exact dependency graph used to decide which files are independent. Those are details to verify before relying on cache results in a demanding CI environment.
Strict Mode and the Catch Variable Trade-off
Strict mode gives the tool a broader definition of uncovered typing, but it also changes what a passing project means. The README says type arguments containing `any` count as uncovered and that several assertion forms are counted too. It also documents exclusions for some assertion patterns. This is useful for teams that want to expose `Promise<any>` or similar indirect escapes, not just a bare `any` annotation.
Catch variables receive separate treatment because the README identifies them as the largest obstacle to reaching 100 percent in some codebases. With `--ignore-catch`, a catch variable can be handled as shown in the documentation:
try {
await ...
} catch (anyErr) {
const err = <Error> anyErr
}The example converts the catch value to `Error` with an assertion. The README presents `--ignore-catch --at-least 100` as a way to pursue 100 percent coverage for this pattern. That does not mean the assertion proves runtime safety. It changes the accounting policy around the catch variable, so readers should distinguish a metric target from a sound runtime error-handling design.
Maintenance, License, and Appropriate Alternatives
The repository is not archived, and its last push was on 2026-10-13. It has no GitHub releases, and the README does not document a release schedule or compatibility matrix. Upgrade cost therefore cannot be reduced to a claim of frequent releases. The package depends on `typescript`, and stricter checks may change the coverage rate in strict mode, so upgrading TypeScript or the CLI can affect policy results.
The repository identifies its license as MIT. That permits use and modification under the terms of the MIT license, but organizations still need to review the license text and their own compliance requirements. This is a repository-specific licensing statement, not legal advice.
A real alternative is to use a general TypeScript linting and static-analysis setup that reports unsafe code patterns and compiler diagnostics as part of a broader quality policy. type-coverage instead focuses on a numerical identifier coverage ratio and offers migration-oriented controls such as `--at-least`, `--ignore-files`, and `--update`. It does not document compiler diagnostics as its primary output, except for the separate `--report-semantic-error` option. That difference matters for teams that want one precise migration metric rather than a full analysis report.
Editorial conclusion
Teams adopting TypeScript incrementally or tightening loose types should evaluate type-coverage, while projects wanting a full static analysis report or a general-purpose linting framework should not treat it as a replacement. Before adoption, verify how your TypeScript version and compiler options affect the result, then test `--strict`, `--detail`, and the threshold you intend to enforce.
Frequently asked questions
How do I install type-coverage?
The README documents `yarn global add type-coverage typescript`, followed by running `type-coverage` from the project directory.
What does --strict change in type-coverage?
It counts `any` inside type arguments and treats documented assertion forms as uncovered. It also enables unused ignore-line reporting by default, and future minor releases may add stricter checks that lower the reported rate.
Can type-coverage enforce a CI threshold?
Yes. Use `--at-least` to fail below a minimum rate or `--is` to require an exact rate. A `typeCoverage` section in `package.json` can store the configuration, including `atLeast`.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/plantain-00-type-coverage)Was this useful?