Guide
Get Started

Get Started

The example below shows how a type testing can help to debug a utility type.

Prerequisites

This guide recommends using the latest Long Term Support (LTS) release of Node.js (the minimum required version is 18.19). To learn more, see the System Requirements page.

Install TSTyche

Use your favorite package manager to add tstyche (and optionally typescript) to a project:

npm add -D tstyche typescript

It is recommended to create a tsconfig.json (opens in a new tab) file as well. Run tsc --init and TypeScript will generate it.

The following steps assume that you installed the typescript package and added the tsconfig.json file. TSTyche works just fine without a TSConfig file and TypeScript installed. To learn more see the JavaScript Project page.

Define a Type

Create a MethodLikeKeys.ts file with the following content:

./MethodLikeKeys.ts
type MethodLike = (...args: any) => any;
 
export type MethodLikeKeys<T> = keyof {
  [K in keyof T as T[K] extends MethodLike ? K : never]: T[K];
};

The MethodLikeKeys utility should construct a union type by picking up names of method like keys of the T type.

Add a Type Test

Create a MethodLikeKeys.tst.ts file in the same directory:

./MethodLikeKeys.tst.ts
import { expect } from "tstyche";
import type { MethodLikeKeys } from "./MethodLikeKeys.js";
 
interface Sample {
  description: string;
  getLength: () => number;
  getWidth?: () => number;
}
 
expect<MethodLikeKeys<Sample>>().type.toBe<"getLength" | "getWidth">();

Here the expect() function defines an easy to read assertion. There are two method like keys in the Sample interface, hence the resulting type must be "getLength" | "getWidth".

By convention, it is recommended to suffix the functional tests with .test.* and the type tests with .tst.*. To learn more, see the TypeScript Project page.

Run the Type Test

All is set. Tell TSTyche to run the type test:

npx tstyche

You should see similar report:

uses TypeScript 5.5.2 with ./tsconfig.json
 
fail ./MethodLikeKeys.tst.ts
 
Error: Type '"getLength"' is not identical to type '"getLength" | "getWidth"'.
 
   8 | }
   9 |
  10 | expect<MethodLikeKeys<Sample>>().type.toBe<"getLength" | "getWidth">();
     |                                            ~~~~~~~~~~~~~~~~~~~~~~~~
  11 |
 
       at ./MethodLikeKeys.tst.ts:10:44

On the first line you see the TypeScript version used for this test run. It is followed by a path to the TSConfig file from which the compiler configuration was loaded.

The rest reports that the test has failed and explains the problem.

Iterate

The getWidth key is marked as optional and was not picked up by the MethodLikeKeys type. Here is the fixed type:

export type MethodLikeKeys<T> = keyof {
  [K in keyof T as Required<T>[K] extends MethodLike ? K : never]: T[K];
};

Run the test again and it will pass:

uses TypeScript 5.5.2 with ./tsconfig.json
 
pass ./MethodLikeKeys.tst.ts