Skip to content

What it is

ts-jest is a Jest transformer that runs TypeScript tests with full type checking during the test run.

Configure Jest to use the ts-jest preset. It compiles each test file with tsc, reporting type errors as test failures.

Installation

npm install -D ts-jest @types/jest

Getting started

The smallest useful thing you can do with it, and what each part means.

Configuration
import type { Config } from 'jest';

const config: Config = {
  preset: 'ts-jest',
  testEnvironment: 'node',
  transform: {
    '^.+\\.tsx?$': ['ts-jest', {
      // isolatedModules is much faster but skips type checking.
      isolatedModules: false,
      tsconfig: 'tsconfig.test.json',
    }],
  },
  moduleNameMapper: { '^@/(.*)$': '<rootDir>/src/$1' },
};

export default config;
moduleNameMapper must mirror the paths in tsconfig — Jest does not read them, so aliases that compile fine will fail to resolve at test time.

Advanced usage

Where the library earns its place over a simpler alternative.

Typed mocks
import { mocked } from 'jest-mock';
import { fetchBook } from './api';

jest.mock('./api');

const mockFetch = mocked(fetchBook);  // keeps the original signature

test('returns the book', async () => {
  mockFetch.mockResolvedValue({ id: '42', title: 'Dune' });

  // A wrong shape here is a compile error, not a runtime surprise.
  await expect(getBookTitle('42')).resolves.toBe('Dune');
  expect(mockFetch).toHaveBeenCalledWith('42');
});
mocked preserves the real signature, so mock return values are checked against what the function actually promises — the main reason to use ts-jest over Babel.

Errors and fixes

The failures you are most likely to hit, and what actually resolves them.

Cannot find module '@/thing' from test
Jest does not read tsconfig paths. Add the equivalent entry to moduleNameMapper.
Tests are slow
Type checking each file is the cost. Enable isolatedModules for speed, accepting that types go unchecked in the run.

Best practices

  • Keep type checking on unless test runs become a bottleneck; it is the reason to use ts-jest at all.
  • Mirror tsconfig paths in moduleNameMapper.
  • Consider Vitest for new projects — it handles TypeScript natively and is faster.
  • Use a separate tsconfig.test.json so test-only types do not leak into the build.

Background

Why it exists, and what it was reacting to.

ts-jest exists because Jest's Babel transform strips types without checking them. ts-jest uses the real compiler, so a type error fails the test rather than passing silently.