Walkthrough
This page offers a quick overview of the most important features 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.
Integrating into Unit Tests
The assertions can be mixed into unit tests as well:
function toMilliseconds(value: number) {
if (typeof value === "number" && !Number.isNaN(value)) {
return value * 1000;
}
throw new Error("Not a number");
}
import assert from "node:assert";
import test from "node:test";
import * as tstyche from "tstyche";
import { toMilliseconds } from "../toMilliseconds.js";
test("toMilliseconds", () => {
const sample = toMilliseconds(10);
assert.equal(sample, 10_000);
tstyche.expect(sample).type.toBe<number>();
// Will pass as a type test and not throw at runtime
tstyche.expect(toMilliseconds).type.not.toBeCallableWith("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 { describe, expect, test } from "tstyche";
import type * as tstyche from "tstyche/tstyche";
test("all options are optional", () => {
expect<tstyche.ConfigFileOptions>().type.toBeAssignableWith({});
});
describe("ConfigFileOptions", () => {
test("'failFast' option", () => {
expect<Pick<tstyche.ConfigFileOptions, "failFast">>().type.toBe<{
failFast?: boolean;
}>();
});
test("'target' option", () => {
expect<Pick<tstyche.ConfigFileOptions, "target">>().type.toBe<{
target?: Array<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:
describe.only("ConfigFileOptions", () => {
test.skip("'failFast' option", () => {
// ...
});
test("'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>;
}>();
Expecting Errors
Speaking of assertions and errors, TSTyche has a special .toRaiseError()
matcher. It checks if the provided type or expression raises a particular TypeScript error:
import { expect } from "tstyche";
function firstItem<T>(target: Array<T>): T | undefined {
return target[0];
}
expect(firstItem()).type.toRaiseError("Expected 1 argument");