>
>
Join the Hardhat team! We are hiring
>
>

#Using TypeScript

In this guide, we will go through the steps to get a Hardhat project working with TypeScript. This means that you can write your Hardhat config, tasks, scripts and tests in TypeScript.

For a general overview of using Hardhat refer to the Getting started guide.

# Enabling TypeScript support

Hardhat will automatically enable its TypeScript support if your config file ends in .ts and is written in valid TypeScript. This requires a few changes to work properly.

#Installing dependencies

TIP

If you installed @nomicfoundation/hardhat-toolbox using npm 7 or higher, you don't need to follow these steps.

Hardhat uses TypeScript and ts-node under the hood, so you need to install them. To do it, open your terminal, go to your Hardhat project, and run:

npm 7+
npm 6
yarn
npm install --save-dev ts-node typescript
npm install --save-dev ts-node typescript
yarn add --dev ts-node typescript

To be able to write your tests in TypeScript, you also need these packages:

npm 7+
npm 6
yarn
npm install --save-dev chai@4 @types/node @types/mocha @types/chai@4
npm install --save-dev chai@4 @types/node @types/mocha @types/chai@4
yarn add --dev chai@4 @types/node @types/mocha @types/chai@4

#TypeScript configuration

You can easily turn a JavaScript Hardhat config file into a TypeScript one. Let's see how this is done starting with a fresh Hardhat project.

Open your terminal, go to an empty folder, run npx hardhat init, and go through the steps to create a JavaScript project. When you're done your project directory should look something like this:

$ ls -l
total 1200
drwxr-xr-x    3 pato  wheel      96 Oct 20 12:50 contracts/
-rw-r--r--    1 pato  wheel     567 Oct 20 12:50 hardhat.config.js
drwxr-xr-x  434 pato  wheel   13888 Oct 20 12:52 node_modules/
-rw-r--r--    1 pato  wheel  604835 Oct 20 12:52 package-lock.json
-rw-r--r--    1 pato  wheel     460 Oct 20 12:52 package.json
drwxr-xr-x    3 pato  wheel      96 Oct 20 12:50 ignition/modules/
drwxr-xr-x    3 pato  wheel      96 Oct 20 12:50 test/

Then, you should follow the steps mentioned in the Installing dependencies section above.

Now, we are going to rename the config file from hardhat.config.js to hardhat.config.ts, just run:

mv hardhat.config.js hardhat.config.ts

We need to make a single change to your config for it to work with TypeScript: you must use import/export instead of require/module.exports.

By using TypeScript, you can also type your configuration, which will save you from typos and other mistakes.

For example, the sample project's config turns from this:

require("@nomicfoundation/hardhat-toolbox");

/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
  solidity: "0.8.24",
};

into this:

import { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-toolbox";

const config: HardhatUserConfig = {
  solidity: "0.8.24",
};

export default config;

Finally, you need to create a tsconfig.json file. Here's our recommended one:

{
  "compilerOptions": {
    "target": "es2020",
    "module": "commonjs",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true,
    "resolveJsonModule": true
  }
}

And that's really all it takes. Now you can write your config, tests, tasks and Ignition modules in TypeScript.

# Type-checking your project

For performance reasons, Hardhat won't type-check your project when you run a task. You can explicitly enable type-checking with the --typecheck flag.

For example, if you run npx hardhat test and one of your tests has a compilation error, the test task will be executed anyway. But if you run npx hardhat test --typecheck, Hardhat will detect and throw the compilation error before starting to run the tests.

Since type-checking adds significant overhead, we recommend to do it only in your CI or in pre-commit/pre-push hooks.

# Writing tests and scripts in TypeScript

When using JavaScript, all the properties in the Hardhat Runtime Environment are injected into the global scope. When using TypeScript nothing will be available in the global scope and you will need to import everything explicitly using, for example, import { ethers } from "hardhat".

Follow the Getting started guide and create a TypeScript project for a complete example on how to write tests using TypeScript.

# Type-safe smart contract interactions

TIP

If you installed @nomicfoundation/hardhat-toolbox you can skip this section, as it includes @typechain/hardhat.

If you want Hardhat to generate types for your smart contract you should install and use @typechain/hardhat. It generates typing files (*.d.ts) based on ABI's, and it requires little to no configuration.

# Support for path mappings

Typescript allows defining custom path mappings via the paths configuration option:

{
  compilerOptions: {
    paths: { "~/*": ["src/*"] },
    // ...Other compilerOptions
  },
}

To support this option when running Hardhat tests or scripts, you need to install the package tsconfig-paths and register it in your hardhat.config.ts:

import { HardhatUserConfig } from "hardhat/config";

// This adds support for typescript paths mappings
import "tsconfig-paths/register";

const config: HardhatUserConfig = {
  // Your type-safe config goes here
};

export default config;

# Running your tests and scripts directly with ts-node

When running Hardhat scripts without the CLI, you need to use ts-node's --files flag.

This can also be enabled with TS_NODE_FILES=true.