A preprocessor for Jest to snapshot test TypeScript declaration (.d.ts) files
- Install
- Usage
- Writing Tests
- Patterns
- Testing
- Configs
- Generate diff-friendly snapshots
- Reporter
- FAQ
- Development
- Related
- License
# using npm
npm install --save-dev dts-jest jest typescript
# using yarn
yarn add --dev dts-jest jest typescript
-
require
jest@>=28
andtypescript@>=4
dts-jest jest typescript 26 >=28 >=4 25 >=28 <30 >=2.3 <5 24 27 >=2.3 <5 23 >=22 <27 >=2.3 <5
Modify your Jest config so that looks something like:
(./package.json)
{
"scripts": {
"test": "jest"
},
"jest": {
"moduleFileExtensions": ["ts", "js", "json"],
"testRegex": "/dts-jest/.+\\.ts$",
"transform": {"/dts-jest/.+\\.ts$": "dts-jest/transform"}
}
}
This setup allow you to test files **/dts-jest/**/*.ts
via dts-jest
.
The test cases must start with a comment @dts-jest
, and the next line should be an expression that you want to test its type or value.
(./dts-jest/example.ts)
// @dts-jest:pass:snap
Math.max(1);
// @dts-jest:pass
Math.min(1, 2, 3); //=> 1
// @dts-jest:fail:snap
Math.max('123');
// @ts-expect-error:snap
Math.max('123');
// @dts-jest[flags] [description]
expression //=> expected
// @ts-expect-error[flags] [description]
expression //=> expected
Note: @ts-expect-error
is treated as an alias of @dts-jest:fail
in dts-jest
.
- description
- optional
- default:
expression
- flag
- optional
- for test
- for type assertion
- default: none
:show
:console.log(type)
:pass
:expect(() => type)
.not
.toThrow()
:fail
:expect(() => type)
.toThrow()
:snap
:- snapshot inferred type or diagnostic message
expect(type)
.toMatchSnapshot()
expect(type)
.toThrowErrorMatchingSnapshot()
:not-any
:expect(type)
.not
.toBe("any")
- expected
- optional
//=> expected
or/*=> expected */
- for value assertion
- default: none
?
:console.log(value)
:error
:expect(() => value)
.toThrow()
:no-error
:expect(() => value)
.not
.toThrow()
- others:
expect(value)
.toEqual(expected)
Test cases after this pattern will be marked as that group.
// @dts-jest:group[flag] [description]
If you need a block scope for your tests you can use a Block Statement.
// @dts-jest:group[flag] [description]
{
// your tests
}
- description
- default:
''
- default:
- flag
- default:
describe
:only
:describe.only
:skip
:describe.skip
- default:
File-level config uses the first comment to set, only docblock will be detected.
/** @dts-jest [action:option] ... */
- action:
enable
: set totrue
disable
: set tofalse
- option:
It's recommended you to run Jest in watching mode via --watch
flag.
npm run test -- --watch
NOTE: If you had changed the version of dts-jest
, you might have to use --no-cache
flag since Jest may use the older cache.
After running the example tests with npm run test
, you'll get the following result:
PASS tests/example.ts
Math.max(1)
✓ (type) should not throw error
✓ (type) should match snapshot
Math.max('123')
✓ (type) should throw error
✓ (type) should match snapshot
Math.min(1, 2, 3)
✓ (type) should not throw error
Snapshot Summary
› 2 snapshots written in 1 test suite.
Test Suites: 1 passed, 1 total
Tests: 5 passed, 5 total
Snapshots: 2 added, 2 total
Time: 0.000s
Ran all test suites.
Since snapshot testing will always pass and write the result at the first time, it's reommended you to use :show
flag to see the result first without writing results.
(./dts-jest/example.ts)
// @dts-jest:pass:show
Math.max(1);
// @dts-jest:fail:show
Math.max('123');
// @dts-jest:pass
Math.min(1, 2, 3); //=> 1
PASS dts-jest/example.ts
Math.max(1)
✓ (type) should show report
✓ (type) should not throw error
Math.max('123')
✓ (type) should show report
✓ (type) should throw error
Math.min(1, 2, 3)
✓ (type) should not throw error
Test Suites: 1 passed, 1 total
Tests: 5 passed, 5 total
Snapshots: 0 total
Time: 0.000s
Ran all test suites.
console.log dts-jest/example.ts:2
Inferred
Math.max(1)
to be
number
console.log dts-jest/example.ts:5
Inferring
Math.max('123')
but throw
Argument of type '"123"' is not assignable to parameter of type 'number'.
Configs are in _dts_jest_
field of Jest config globals
.
There are several options
- test_type
- default:
true
- enable type testing
- file-level config available
- default:
- test_value
- default:
false
- enable value testing
- file-level config available
- default:
- enclosing_declaration
- default:
false
- unwrap type alias
- default:
- typescript
- default:
typescript
(node resolution) - specify which path of typescript to use
<cwd>
available
- default:
- compiler_options
- default:
{}
- specify which path of
tsconfig.json
(string)or compilerOptions (object)(deprecated, does not supporttypeRoots
for object) to use
- default:
- type_format_flags
- default:
ts.TypeFormatFlags.NoTruncation
- specify type format
- default:
- transpile
- default:
true
- transpile code before testing, only affect tests that needs to test value
- transpiling code will cause line number incorrect, it's better to disable this option if possible
- default:
For example:
(./package.json)
{
"jest": {
"globals": {
"_dts_jest_": {
"compiler_options": {
"strict": true,
"target": "es6"
}
}
}
}
}
Originally, snapshots and source content are in different files, it is hard to check their difference before/after, so here comes the dts-jest-remap
for generating diff-friendly snapshots.
(./tests/example.ts)
// @dts-jest:snap
Math.max(1, 2, 3);
(./tests/__snapshots__
/example.ts.snap) note this file is generated by Jest
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Math.max(1, 2, 3) 1`] = `"number"`;
This command will combine both snapshots and source content in one file:
dts-jest-remap ./tests/example.ts --outDir ./snapshots
(./snapshots/example.ts)
// @dts-jest:snap -> number
Math.max(1, 2, 3);
Usage: dts-jest-remap [--outDir <path>] [--rename <template>] <TestFileGlob> ...
Options:
--check, -c Throw error if target content is different from output
content [boolean]
--help, -h Show help [boolean]
--listDifferent, -l Print the filenames of files that their target content is
different from output content [boolean]
--outDir, -o Redirect output structure to the directory [string]
--rename, -r Rename output filename using template {{variable}},
available variable: filename, basename, extname [string]
--typescript, -t Specify which TypeScript source to use [string]
--version, -v Show version number [boolean]
If you'd like to know which typescript you are using, add dts-jest/reporter
to your Jest reporters, for example:
{
"reporters": [
"default",
"dts-jest/reporter"
]
}
It'll show the TS version and path after testing:
[dts-jest] using TypeScript v0.0.0 from path/to/typescript
Compiler option 'lib' requires a value of type list
- Arrays in
jest
>globals
>_dts_jest_
will be transformed into objects. - Consider to use
setupFiles
to set configs (globals._dts_jest_ = { ... }
). - See jest#2093 for details.
- Arrays in
Debug Failure
- This is mostly caused by regex literal due to the printer bug TypeScript#18071 (fixed in TS v2.6).
- Workaround: use regex instance instead, e.g.
new RegExp('something')
.
# lint
yarn run lint
# test
yarn run test
# build
yarn run build
- dtslint: A utility built on TSLint for linting TypeScript declaration (.d.ts) files
- typings-checker: Positive and negative assertions about TypeScript types and errors
MIT © Ika