Release Notes
This page lists breaking changes and notable new features. Please be sure to read the release notes before upgrading from a previous version.
The detailed changelog can be found in TSTyche repository on GitHub .
TSTyche 3.2
TSTyche 3.2 adds the new checkSourceFiles configuration option.
Configuration
checkSourceFiles
Enable type error reporting for source files.
When checkSourceFiles is enabled, all imported or ambient .d.ts files in the project (not including files from the node_modules directories) are checked for type errors.
TSTyche 3.1
TSTyche 3.1 adds the new rejectAnyType and rejectNeverType configuration options and adds support for testing on a range of TypeScript versions.
Configuration
rejectAnyType
Reject the any type passed as an argument to the expect() function or a matcher.
For instance, the following test passes even when the return type accidentally resolves to any:
import { } from "query";
import { } from "tstyche";
(({ : "sample" }))..<string>();
(({ : 123 }))..<number>();Adding .not.toBe<any>() solves this, but rejectAnyType does the same without the boilerplate.
rejectNeverType
Reject the never type passed as an argument to the expect() function or a matcher.
For instance, the following test passes even when the Result type accidentally resolves to never:
import { type , } from "result";
import { } from "tstyche";
(("sample"))..<<string>>();
((123))..<<number>>();Adding .not.toBe<never>() solves this, but rejectNeverType does the same without the boilerplate.
target
TSTyche now allows specifying a range of TypeScript versions.
For example, the range >=5.5 gets expanded to: 5.5, 5.6, 5.7 and so on. Newly released versions are added to the list as soon as they become available.
To set an upper bound, the intersection of two ranges can be used: >=5.0 <5.3. In this case, only 5.0, 5.1 and 5.2 are included.
Ranges and versions can be combined:
{
"target": [">=5.0 <5.3", "5.4.2", ">5.5"]
}Command Line
--list
Print the list of supported versions of the typescript package and exit.
--target
A range of TypeScript versions can be specified:
# Run tests using TypeScript 5.5, 5.6, 5.7, etc
tstyche --target '>=5.5'
# Run tests using TypeScript 5.0, 5.1 and 5.2
tstyche --target '>=5.0 <5.3'
# Ranges and versions can be combined
tstyche --target '>=5.0 <5.3, 5.4.2, >5.5'TSTyche 3.0
TSTyche 3.0 ships with the new tsconfig option, support for a custom npm registry, the new omit() and pick() type utilities, support for reporters and plugins, programmatic usage refinements and performance improvements.
Requirements
The minimum required Node.js version is 18.19. It is recommended to use the latest LTS release .
Matchers
Breaking! The deprecated .toBeAssignable() and .toEqual() matchers are removed.
.toHaveProperty()
The .toHaveProperty() matcher is now able to check index signatures:
import { expect } from "tstyche";
expect<Record<string, unknown>>().type.toHaveProperty("sample");
expect<Record<number, unknown>>().type.not.toHaveProperty("sample");
interface DataProps {
[key: `data-${string}`]: string;
}
expect<DataProps>().type.toHaveProperty("data-sample");.toMatch()
The .toMatch() matcher is deprecated. The Omit and Pick utility types or the new omit() and pick() type utilities should be used for subtype testing.
.toRaiseError()
The .toRaiseError() matcher now takes regular expressions as well:
import { expect } from "tstyche";
interface Matchers<R, T = unknown> {
[key: string]: (expected: T) => R;
}
// Pattern matching the error message
expect<Matchers>().type.toRaiseError(/between \d and \d type arguments/);
expect<Matchers>().type.toRaiseError(/generic .+ requires .+ type arguments/i);
// The exact error message
expect<Matchers>().type.toRaiseError(
/^Generic type 'Matchers<R, T>' requires between 1 and 2 type arguments.$/,
);Configuration
tsconfig
The strategy used to find the TSConfig file.
The following can be specified:
"findup", automatically discovers the nearesttsconfig.jsonfile (default)"ignore", does not look for anytsconfig.jsonand uses the defaults- a path, like
"./tsconfig.test.json", loads a specifictsconfig.jsonfile
{
"tsconfig": "./tsconfig.test.json"
}If a particular test file is not included in a TSConfig file, TSTyche falls back to default compiler options.
Environment Variables
Breaking! The TSTYCHE_TYPESCRIPT_PATH environment variable is removed. Use TSTYCHE_TYPESCRIPT_MODULE instead.
TSTYCHE_NPM_REGISTRY
The base URL of the npm registry to use.
TSTYCHE_TYPESCRIPT_MODULE
TSTYCHE_TYPESCRIPT_MODULE is the new name of TSTYCHE_TYPESCRIPT_PATH. The value is now resolved using the import.meta.resolve() function.
Type Utilities
TypeScript ships utility types like Omit or Pick that reshape types. They can also be useful when testing types. If you are testing types of expressions, use the omit() or pick() type utilities to get the same results.
The utilities only reshape types. At runtime they return the same object that was passed as an argument.
omit()
The omit() type utility reshapes type of the given object by removing the specified keys:
import { expect, omit, pick } from "tstyche";
class Queue<T> {
entries: Array<T> = [];
get size(): number {
return this.entries.length;
}
enqueue(item: T): void {
this.entries.push(item);
}
}
expect(omit(new Queue(), "enqueue", "entries")).type.toBe<{
readonly size: number;
}>();
// Equivalent to the 'Omit' utility type
expect<Omit<Queue<string>, "enqueue" | "entries">>().type.toBe<{
readonly size: number;
}>();pick()
The pick() type utility reshapes type of the given object by keeping only the specified keys:
import { expect, omit, pick } from "tstyche";
class Queue<T> {
entries: Array<T> = [];
get size(): number {
return this.entries.length;
}
enqueue(item: T): void {
this.entries.push(item);
}
}
expect(pick(new Queue(), "size")).type.toBe<{ readonly size: number }>();
// Equivalent to the 'Pick' utility type
expect<Pick<Queue<string>, "size">>().type.toBe<{ readonly size: number }>();Reporters
Reporters control how TSTyche formats test results. By default, the built-in list and summary reporters are used.
A custom reporter is a class that implements the on() method:
export default class CustomReporter {
/**
* @param {import("tstyche/tstyche").Event} event
*/
on([event, payload]) {
if (event === "run:start") {
console.info("Hello from custom reporter!");
for (const task of payload.result.tasks) {
console.info(task.filePath);
}
}
}
}Plugins
The plugins allow changing the behavior of TSTyche.
A plugin is an object with one or more hooks:
/**
* @type {import("tstyche/tstyche").Plugin}
*/
export default {
name: "example-plugin",
config(resolvedConfig) {
return { ...resolvedConfig, testFileMatch: [] };
},
async select() {
return await getTestFilesSomehow(this.resolvedConfig);
},
};In this example, the config hook disables test file lookup and the select hook returns a list of test files.
Programmatic Usage
This release also ships with a refined programmatic API.
import { Config, Runner } from "tstyche/tstyche";
const resolvedConfig = Config.resolve();
const runner = new Runner(resolvedConfig);
await runner.run(["./typetests/toBeNumber.tst.ts"]);To learn more, see the Programmatic Usage page.