Creating a Next.js site with Jest and Typescript

I wanted to try out Next.js as an alternative to Gatsby for a project because I think it will be helpful to have the server-side render do some data fetching for me. In doing so, I needed to configure it to work with Jest and Typescript to work with my usual flow. Getting to this point was not quite as straightforward as I hoped. I was able to piece the things together after about an hour.

First, I added typescript support to my newly created npx create-next-app application by running the following.

yarn add --dev typescript @types/react @types/node

Then I changed, pages/index.js to pages/index.tsx and components/nav.js to components/nav.tsx and ran yarn dev. Next was smart enough to realize what had happened and create a tsconfig.json for me.

After the typescript change, I wanted to get my testing configured by adding both Jest and React Testing Library. Completing the configuration required new dependencies and configuration files. This is where a choice had to be made. If type checking enforcement by Jest is important you will want to use ts-jest but, I was unable to get this to work with styled-jsx. If styled-jsx is more important, you can leverage babel to do the typescript transform for you.

Using ts-jest

yarn add --dev jest @types/jest @testing-library/react @testing-library/jest-dom ts-jest

A typescript config file for Jest to understand jsx tsconfig.jest.json

{
  "compilerOptions": {
    "jsx": "react",
    "allowJs": true,
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "noImplicitAny": true,
    "sourceMap": true,
    "target": "es5"
  }
}

A Jest config for processing the typescript jest.config.js

module.exports = {
  preset: "ts-jest",
  setupFilesAfterEnv: ["<rootDir>/test/setup.ts"],
  globals: {
    "ts-jest": {
      tsConfig: "tsconfig.jest.json"
    }
  }
};

And a setup file to add dom assertions for all tests test/setup.ts

import "@testing-library/jest-dom/extend-expect";

At this point, testing should be working. However, there will be complaints if you are testing code that uses styled-jsx.

Using styled-jsx and @babel/preset-typescript

yarn add --dev jest @types/jest @testing-library/react @testing-library/jest-dom @babel/preset-typescript

A babel config for processing the typescript and styled-jsx babel.config.js

module.exports = {
  presets: ["next/babel", "@babel/preset-typescript"],
  env: {
    test: {
      plugins: ["styled-jsx/babel-test"]
    }
  }
};

And a setup file to add dom assertions for all tests test/setup.ts

import "@testing-library/jest-dom/extend-expect";

A Jest config for running the setup file jest.config.js

module.exports = {
  setupFilesAfterEnv: ["<rootDir>/test/setup.ts"]
};