Walkthrough
An overview of the most important aspects of TSTyche.
How It Works?
The TSTyche test runner does not execute the code. Instead, it passes the code through TypeScript’s type checker and reports back with the result. In a way, you can see TSTyche as a type checker with benefits.
To learn more, see the Introduction page.
Testing Specific Version of TypeScript
TSTyche has everything you need to test against a specific version of TypeScript:
tstyche --target 5.4
The above command runs tests using TypeScript 5.4.5
. You can specify a range of versions as well:
tstyche --target '>=5.6'
To learn more, see the TypeScript Versions page.
Expecting Errors
The downside of // @ts-expect-error
is that it hides any errors found in the line following the comment. To address that, TSTyche requires a fragment of the error message after // @ts-expect-error
and checks if it matches the actual error:
// @ts-expect-error Cannot find name 'add'
.(add);
To learn more, see the documentation of the checkSuppressedErrors
option.
To indicate the purpose of a test, use matchers like .toBeCallableWith()
or .toHaveProperty()
instead of // @ts-expect-error
.
Integrating into Unit Tests
The assertions can be mixed into unit tests as well:
export function (: number) {
if (typeof === "number" && !.()) {
return * 1000;
}
throw new ("Not a number");
}
import from "node:assert";
import from "node:test";
import * as from "tstyche";
import { } from "../toMilliseconds.js";
("toMilliseconds", () => {
const = (10);
.(, 10_000);
.()..<number>();
// Will pass as a type test and not throw at runtime
.()...("20");
});
Use the testFileMatch
configuration option to include files in the test run:
{
"testFileMatch": ["**/*.test.ts", "**/*.tst.ts"]
}
TSTyche assertions and testing helpers are just empty functions returning undefined
. They do nothing when invoked by a JavaScript test runner.
Selecting Test Files
Passing one or more search strings to the tstyche
command runs only the test files with matching paths. For example, if a project structure look like this:
- lastItem.test.ts
- secondItem.test.ts
- lastItem.ts
- secondItem.ts
The following will select only the secondItem.test.ts
file:
tstyche second
Filtering Tests
To organize a larger test file, the describe()
and test()
helpers can be used:
import { , , } from "tstyche";
("all options are optional", () => {
<ConfigFileOptions>()..({});
});
("ConfigFileOptions", () => {
("'failFast' option", () => {
<<ConfigFileOptions, "failFast">>()..<{
?: boolean;
}>();
});
("'target' option", () => {
<<ConfigFileOptions, "target">>()..<{
?: <string>;
}>();
});
});
This is a fragment of TSTyche’s ConfigFileOptions
interface test. The type is generated by a script and this test makes sure that the resulting code is correct.
While developing similar script, the run mode flags come in handy. Use .only
to focus on or .skip
to skip some of the tests:
.("ConfigFileOptions", () => {
.("'failFast' option", () => {
// ...
});
("'target' option", () => {
// ...
});
});
Tests can be selected by their name straight from the command line through the --only
and --skip
filters:
tstyche --only configFile --skip failFast
Filtering Assertions
TSTyche assertions support the run mode flags too. Besides focusing and skipping you can also mark them as failing. A supposed to fail assertion raises an error only if it passes.
import { expect } from "tstyche";
import type * as tstyche from "tstyche/tstyche";
expect.skip<Pick<tstyche.ConfigFileOptions, "failFast">>().type.toBe<{
failFast?: boolean;
}>();
expect.fail<Pick<tstyche.ConfigFileOptions, "target">>().type.toBe<{
target?: Array<string>;
}>();