Skip to content

A CLI tool to check type coverage for typescript code

License

Notifications You must be signed in to change notification settings

devfolioco/type-coverage

 
 

Repository files navigation

type-coverage

A CLI tool to check type coverage for typescript code

This tool will check type of all identifiers, the type coverage rate = the count of identifiers whose type is not any / the total count of identifiers, the higher, the better.

Dependency Status devDependency Status Build Status: Linux Build Status: Windows Github CI npm version Downloads type-coverage Codechecks

use cases

  • Show progress of long-term progressive migration from existing js code to typescript code.
  • Avoid introducing accidental any by running in CI.

install

yarn global add type-coverage

usage

run type-coverage

arguments

name type description
-p, --project string? tell the CLI where is the tsconfig.json(Added in v1.0)
--detail boolean? show detail(Added in v1.0)
--at-least number? fail if coverage rate < this value(Added in v1.0)
--debug boolean? show debug info(Added in v1.0)
--strict boolean? strict mode(Added in v1.7)
--ignore-catch boolean? ignore catch(Added in v1.13)
--cache boolean? enable cache(Added in v1.10)
--ignore-files string[]? ignore files(Added in v1.14)
-h, --help boolean? show help(Added in v2.5)
--is number? fail if coverage rate !== this value(Added in v2.6)
--update boolean? update "typeCoverage" in package.json to current result(Added in v2.6)
--ignore-unread boolean? allow writes to variables with implicit any types(Added in v2.14)

strict mode

If the identifiers' type arguments exist and contain at least one any, like any[], ReadonlyArray<any>, Promise<any>, Foo<number, any>, it will be considered as any too(Added in v1.7)

Type assertion, like foo as string, foo!, <string>foo will be considered as uncovered, exclude foo as const, <const>foo, foo as unknown(Added in v2.8), and other safe type assertion powered by isTypeAssignableTo(Added in v2.9)

Also, future minor release may introduce stricter type check in this mode, which may lower the type coverage rate

enable cache

save and reuse type check result of files that is unchanged and independent of changed files in .type-coverage directory, to improve speed

ignore catch

If you want to get 100% type coverage then try {} catch {} is the largest blocked towards that.

This can be fixed in typescript with Allow type annotation on catch clause variable but until then you can turn on --ignore-catch --at-least 100.

Your catch blocks should look like

try {
  await ...
} catch (anyErr) {
  const err = <Error> anyErr
}

To have the highest type coverage.

ignore files

This tool will ignore the files, eg: --ignore-files "demo1/*.ts" --ignore-files "demo2/foo.ts"

config in package.json

  "typeCoverage": {
    "atLeast": 99, // same as --at-least (Added in `v1.4`)
    "is": 99, // same as --is (Added in `v2.6`)
    "cache": true, // same as --cache (Added in `v2.11`)
    "debug": true, // same as --debug (Added in `v2.11`)
    "detail": true, // same as --detail (Added in `v2.11`)
    "ignoreCatch": true, // same as --ignore-catch (Added in `v2.11`)
    "ignoreFiles": ["demo1/*.ts", "demo2/foo.ts"], // same as --ignore-files "demo1/*.ts" --ignore-files "demo2/foo.ts" (Added in `v2.11`)
    "project": "tsconfig.json", // same as --project tsconfig.json or -p tsconfig.json (Added in `v2.11`)
    "strict": true, // same as --strict (Added in `v2.11`)
    "suppressError": true, // same as --suppressError (Added in `v2.11`)
    "update": true, // same as --update (Added in `v2.11`)
    "ignoreUnread": true // same as --ignore-unread (Added in `v2.14`)
  },

ignore line

Use type-coverage:ignore-next-line or type-coverage:ignore-line in comment(// or /* */) to ignore any in a line.(Added in v1.9)

try {
  // type-coverage:ignore-next-line
} catch (error) { // type-coverage:ignore-line
}

add dynamic badges of type coverage rate

Use your own project url:

[![type-coverage](https://img.shields.io/badge/dynamic/json.svg?label=type-coverage&prefix=%E2%89%A5&suffix=%&query=$.typeCoverage.atLeast&uri=https%3A%2F%2Fraw.githubusercontent.com%2Fplantain-00%2Ftype-coverage%2Fmaster%2Fpackage.json)](https://github.com/plantain-00/type-coverage)

integrating with PRs

Using codechecks you can integrate type-coverage with GitHub's Pull Requests. See type-coverage-watcher.

type-coverage-watcher

typescript coverage report

Using typescript-coverage-report you can generate typescript coverage report.

typescript-coverage-report

API(Added in v1.3)

import { lint } from 'type-coverage-core'

const result = await lint('.', { strict: true })
export function lint(project: string, options?: Partial<LintOptions>): Promise<FileTypeCheckResult & { program: ts.Program }>
export function lintSync(compilerOptions: ts.CompilerOptions, rootNames: string[], options?: Partial<LintOptions>): FileTypeCheckResult & { program: ts.Program } // Added in `v2.12`

export interface LintOptions {
  debug: boolean,
  files?: string[],
  oldProgram?: ts.Program,
  strict: boolean, // Added in v1.7
  enableCache: boolean, // Added in v1.10
  ignoreCatch: boolean, // Added in v1.13
  ignoreFiles?: string | string[], // Added in v1.14
  fileCounts: boolean, // Added in v2.3
  absolutePath?: boolean, // Added in v2.4
  processAny?: ProccessAny, // Added in v2.7
  ignoreUnreadAnys: boolean, // Added in v2.14
}

export interface FileTypeCheckResult {
  correctCount: number
  totalCount: number
  anys: FileAnyInfo[]
  fileCounts: { // Added in v2.3
    correctCount: number,
    totalCount: number,
  }[]
}

export interface FileAnyInfo {
  line: number
  character: number
  text: string
  kind: FileAnyInfoKind //  Added in v2.13
}

export const enum FileAnyInfoKind {
  any = 1, // any
  containsAny = 2, // Promise<any>
  unsafeAs = 3, // foo as string
  unsafeTypeAssertion = 4, // <string>foo
  unsafeNonNull = 5, // foo!
}

export type ProccessAny = (node: ts.Node, context: FileContext) => boolean

The typescript language service plugin of type-coverage(Added in v2.12)

ts-plugin demo

yarn add ts-plugin-type-coverage -D

{
  "compilerOptions": {
    "plugins": [
      {
        "name": "ts-plugin-type-coverage",
        "strict": true, // for all configurations, see LintOptions above
        "ignoreCatch": true,
      }
    ]
  }
}

For VSCode users, choose "Use Workspace Version", See https://github.com/microsoft/TypeScript/wiki/Writing-a-Language-Service-Plugin#testing-locally, or just use the wrapped plugin below.

VSCode plugin(Added in v2.13)

https://marketplace.visualstudio.com/items?itemName=york-yao.vscode-type-coverage

Configuration is in Preferences - Settings - Extensions - Type Coverage

FAQ

Q: Does this count JavaScript files?

Yes, This package calls Typescript API, Typescript can parse Javascript file(with allowJs), then this package can too.

Changelogs

CHANGELOG for minor and patch release

v2

  1. Move typescript from dependencies to peerDependencies
  2. Move API from package type-coverage to package type-coverage-core
// v1
import { lint } from 'type-coverage'
lint('.', false, false, undefined, undefined, true)

// v2
import { lint } from 'type-coverage-core'
lint('.', { strict: true })

About

A CLI tool to check type coverage for typescript code

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • TypeScript 99.9%
  • JavaScript 0.1%