npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

types-testing

v1.0.0

Published

Test TypeScript types at test runner runtime - Works seamlessly with Jest, Vitest, and Bun.

Readme

types-testing

Test TypeScript types at test runner runtime - Works seamlessly with Jest, Vitest, and Bun.

License NPM Latest NPM Downloads NPM Min Size

CI CodeQL Codecov Type Coverage

  • Types Testing: Ensures TypeScript types or definitions are tested.
  • Readable Tests: Uses the expect-assertion style for clean and easy-to-read types testing.
  • Variative Assertions: Provides assertions like toBe, toBeNever, toBeUnknown, toBeVoid, toBeAny, and more for checking.
  • Framework Agnostic: Seamlessly works with Jest (TypeScript), Vitest, Bun Test, and other TypeScript testing frameworks.
  • Easy Integration: Integrates smoothly into TypeScript testing frameworks.
  • No Special Comments Needed: No need to add special comment like @ts-expect-error, just write clean and readable types tests code inside the existing test suite.
  • Runtime Stack Traces: Offers detailed stack traces for failed tests.

Example Showcases

Here is an example of how types-testing tests TypeScript types or definitions (sources):

// example.test.ts
import { join } from 'node:path';
import { TypesTesting } from 'src';
import exampleModule from './example-module';
import * as ExampleTypes from './example-types';

if (process.versions.bun) {
  let bunTest = (await import('bun:test')).default;

  if (!bunTest) {
    bunTest = await import('bun:test');
  }

  global.describe = bunTest.describe as unknown as typeof global.describe;
  global.test = bunTest.test as unknown as typeof global.test;
} else if (process.env.VITEST) {
  const vitest = await import('vitest');
  global.describe = vitest.describe as unknown as typeof global.describe;
  global.test = vitest.test as unknown as typeof global.test;
}

const basePath = join(process.cwd(), '__tests__/__example');
const { expectType } = new TypesTesting({
  basePath,
  tsConfig: 'tsconfig.json'
}).prepare();

describe('example-module', () => {
  test(`exampleModule.name type is 'example-module'`, () => {
    // using runtime argument
    expectType(exampleModule.name).toBe<'example-module'>();
    expectType(exampleModule.name).toBeStringLiteral();

    // using type argument
    expectType<typeof exampleModule.name>().toBe<'example-module'>();
    expectType<typeof exampleModule.name>().toBeString();
  });

  test(`exampleModule.getName type is function without parameter and return 'example-module'`, () => {
    // using runtime argument
    expectType(exampleModule.getName).toBe<() => 'example-module'>();
    expectType(exampleModule.getName).toBe<{
      (): 'example-module';
    }>();
    expectType(exampleModule.getName()).toBe<'example-module'>();

    // using type argument
    expectType<typeof exampleModule.getName>().toBe<() => 'example-module'>();
    expectType<typeof exampleModule.getName>().toBe<{
      (): 'example-module';
    }>();
    expectType<
      ReturnType<typeof exampleModule.getName>
    >().toBe<'example-module'>();
  });

  if (process.env.FAIL_EXAMPLE_TEST) {
    test('fail example', () => {
      expectType(exampleModule.name).toBe<string>();
    });
  }
});

describe('example-types', () => {
  test('KeyOf is utility types for getting keys from object type', () => {
    expectType<ExampleTypes.KeyOf<{ a: 1; b: 2; c: 3 }>>().toBe<
      'a' | 'b' | 'c'
    >();
  });

  if (process.env.FAIL_EXAMPLE_TEST) {
    test('fail example', () => {
      expectType<ExampleTypes.KeyOf<{ a: 1; b: 2; c: 3 }>>().toBe<1 | 2 | 3>();
    });
  }
});

// example-module.js
export default {
  name: 'example-module',
  getName(){
    return this.name;
  }
};

// example-module.d.ts
declare const exampleModule: {
  name: 'example-module';
  getName(): 'example-module';
}

export default exampleModule;

// example-types.ts
export type KeyOf<T> = T extends T ? keyof T : never;
 FAIL  __tests__/__example/example.test.ts
  example-module
    √ exampleModule.name type is 'example-module' (12 ms)
    √ exampleModule.getName type is function without parameter and return 'example-module' (5 ms)
    × fail example (2 ms)
  example-types
    √ KeyOf is utility types for getting keys from object type (1 ms)
    × fail example (1 ms)

  ● example-module › fail example

    TypesTestingError: expectType<received>().toBe<expected>()

    Expected type: string
    Received type: "example-module"


      56 |   if (process.env.FAIL_EXAMPLE_TEST) {
      57 |     test('fail example', () => {
    > 58 |       expectType(exampleModule.name).toBe<string>();
         |                                      ^
      59 |     });
      60 |   }
      61 | });

      at Object.<anonymous> (__tests__/__example/example.test.ts:58:38)

  ● example-types › fail example

    TypesTestingError: expectType<received>().toBe<expected>()

    Expected type: 1 | 2 | 3
    Received type: "a" | "b" | "c"


      70 |   if (process.env.FAIL_EXAMPLE_TEST) {
      71 |     test('fail example', () => {
    > 72 |       expectType<ExampleTypes.KeyOf<{ a: 1; b: 2; c: 3 }>>().toBe<1 | 2 | 3>();
         |                                                              ^
      73 |     });
      74 |   }
      75 | });

      at Object.<anonymous> (__tests__/__example/example.test.ts:72:62)

Test Suites: 1 failed, 1 total
Tests:       2 failed, 3 passed, 5 total
Snapshots:   0 total
Time:        2.336 s, estimated 3 s
 RUN  v3.1.2 /@codeismyid/types-testing

 ❯ __tests__/__example/example.test.ts (5 tests | 2 failed) 12ms
   ✓ example-module > exampleModule.name type is 'example-module' 6ms
   ✓ example-module > exampleModule.getName type is function without parameter and return 'example-module' 2ms
   × example-module > fail example 2ms
     → expectType<received>().toBe<expected>()

Expected type: string
Received type: "example-module"

   ✓ example-types > KeyOf is utility types for getting keys from object type 0ms
   × example-types > fail example 1ms
     → expectType<received>().toBe<expected>()

Expected type: 1 | 2 | 3
Received type: "a" | "b" | "c"


⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Failed Tests 2 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯

 FAIL  __tests__/__example/example.test.ts > example-module > fail example
TypesTestingError: expectType<received>().toBe<expected>()

Expected type: string
Received type: "example-module"

 ❯ __tests__/__example/example.test.ts:55:38
     56|   if (process.env.FAIL_EXAMPLE_TEST) {
     57|     test('fail example', () => {
     58|       expectType(exampleModule.name).toBe<string>();
       |                                      ^
     59|     });
     60|   }

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/2]⎯

 FAIL  __tests__/__example/example.test.ts > example-types > fail example
TypesTestingError: expectType<received>().toBe<expected>()

Expected type: 1 | 2 | 3
Received type: "a" | "b" | "c"

 ❯ __tests__/__example/example.test.ts:69:62
     70|   if (process.env.FAIL_EXAMPLE_TEST) {
     71|     test('fail example', () => {
     72|       expectType<ExampleTypes.KeyOf<{ a: 1; b: 2; c: 3 }>>().toBe<1 | 2 | 3>();
       |                                                              ^
     73|     });
     74|   }

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/2]⎯


 Test Files  1 failed (1)
      Tests  2 failed | 3 passed (5)
   Start at  21:39:24
   Duration  2.78s (transform 185ms, setup 0ms, collect 2.33s, tests 12ms, environment 0ms, prepare 122ms)
bun test v1.1.42 (50eec002)

__tests__/__example/example.test.ts:
✓ example-module > exampleModule.name type is 'example-module' [16.00ms]
✓ example-module > exampleModule.getName type is function without parameter and return 'example-module' [15.00ms]
53 |     >().toBe<'example-module'>();
54 |   });
55 |
56 |   if (process.env.FAIL_EXAMPLE_TEST) {
57 |     test('fail example', () => {
58 |       expectType(exampleModule.name).toBe<string>();
                                          ^
TypesTestingError: expectType<received>().toBe<expected>()

Expected type: string
Received type: "example-module"

      at /@codeismyid/types-testing/__tests__/__example/example.test.ts:58:38
✗ example-module > fail example [16.00ms]
✓ example-types > KeyOf is utility types for getting keys from object type
67 |     >();
68 |   });
69 |
70 |   if (process.env.FAIL_EXAMPLE_TEST) {
71 |     test('fail example', () => {
72 |       expectType<ExampleTypes.KeyOf<{ a: 1; b: 2; c: 3 }>>().toBe<1 | 2 | 3>();
                                                                  ^
TypesTestingError: expectType<received>().toBe<expected>()

Expected type: 1 | 2 | 3
Received type: "a" | "b" | "c"

      at /@codeismyid/types-testing/__tests__/__example/example.test.ts:72:62
✗ example-types > fail example [16.00ms]

 3 pass
 2 fail
Ran 5 tests across 1 files. [2.09s]

Installation

# NPM
npm install --save-dev types-testing

# BUN
bun add -d types-testing

Usage

Default Options

import { expectType } from 'types-testing';

describe('test', () => {
  test('test', () => {
    expectType<string>().toBe<string>();
  });
});

Note: prepare function get invoked when expectType is called at the first time with process.cwd() as base path and tsconfig.json as TypeScript configuration file.

Custom Typescript Configuration File

import { expectType, prepare } from 'types-testing';

prepare({ basePath: 'this/is/basepath', tsConfig: 'tsconfig.test.json' });

describe('test', () => {
  test('test', () => {
    expectType<string>().toBe<string>();
  });
});

Extending Typescript Configuration File

import { expectType, prepare } from 'types-testing';

prepare({
  basePath: 'this/is/basepath',
  tsConfig: 'tsconfig.test.json',
  compilerOptions: {
    // add ts compiler options to extends typescript compiler options from tsconfig file
  },
  files: [
    // add included files to extends included files from tsconfig file
  ],
  projectReferences: [
    // add project references to extends project references from tsconfig file.
  ]
});

describe('test', () => {
  test('test', () => {
    expectType<string>().toBe<string>();
  });
});

Configuration Without Typescript Configuration File

import { expectType, prepare } from 'types-testing';

prepare({
  compilerOptions: {
    // add ts compiler options
  },
  files: [
    // add included files
  ]
})

describe('test', () => {
  test('test', () => {
    expectType<string>().toBe<string>();
  });
});

Custom Instance

import { TypesTesting } from 'types-testing';

const { expectType, prepare } = new TypesTesting({ 
  autoPrepare: false,
  basePath: process.cwd(), 
  tsConfig: 'tsconfig.test.json' 
});

describe('test', () => {
  beforeAll(()=>{
    prepare();
  });

  test('test', () => {
    expectType<string>().toBe<string>();
  });
});

Developed With

  • Typescript - Strongly typed programming language that builds on JavaScript.
  • Bun - All-in-one JavaScript runtime & toolkit designed for speed, complete with a bundler, test runner, and Node.js-compatible package manager.

License

The code in this project is released under the MIT License.