TypeChain
TypeChain is a foundational development tool for the Ethereum ecosystem, providing TypeScript bindings for smart contracts. It enables developers to generate static, type-safe interfaces for their Solidity contracts, significantly reducing runtime errors and improving developer experience through autocompletion and compile-time checks. The current stable version is 8.3.2, with frequent patch releases addressing bug fixes and minor updates to support new features or align with major dependency versions (like Ethers.js and Hardhat). TypeChain is highly extensible, supporting various popular web3 libraries and frameworks such as Ethers.js (v5 and v6), Hardhat, Truffle, and Web3.js through dedicated 'targets'. This broad compatibility and its ability to work with both simple JSON ABI files and complex Truffle/Hardhat artifacts distinguish it from more tightly coupled alternatives, making it a ubiquitous tool in professional smart contract development workflows.
Common errors
-
Cannot find module '@typechain/hardhat' or its corresponding type declarations.
cause The Hardhat TypeChain plugin has not been installed or correctly imported/required in your `hardhat.config.ts`.fixRun `npm install --save-dev @typechain/hardhat` to install the plugin. Then, ensure it's imported in `hardhat.config.ts` using `import '@typechain/hardhat';` (for ESM) or `require('@typechain/hardhat');` (for CommonJS). -
Property 'connect' does not exist on type 'BaseContract' (or similar type mismatch errors when interacting with Ethers.js contracts).
cause This error typically indicates a mismatch between the Ethers.js version installed in your project and the TypeChain target configured. For instance, using `ethers@^6.0.0` with types generated by `@typechain/ethers-v5`.fixVerify your `ethers` dependency version (e.g., `ethers@^6.0.0`) and set the TypeChain target accordingly in your `hardhat.config.ts` (e.g., `target: 'ethers-v6'`). Regenerate types after making changes. -
TypeError: Cannot read properties of undefined (reading 'getContractFactory') or Property 'ethers' does not exist on type 'HardhatRuntimeEnvironment'.
cause This often occurs if `@nomicfoundation/hardhat-toolbox` or relevant Hardhat plugins (like `@nomiclabs/hardhat-ethers`) are not installed or correctly imported, preventing Hardhat from exposing the `ethers` object on its runtime environment.fixEnsure `@nomicfoundation/hardhat-toolbox` is installed (`npm install --save-dev @nomicfoundation/hardhat-toolbox`) and imported in `hardhat.config.ts`: `import '@nomicfoundation/hardhat-toolbox';`.
Warnings
- breaking TypeChain requires TypeScript version 4.3 or newer. Using older versions will result in compilation errors or incorrect type generation, as TypeChain leverages modern TypeScript features.
- gotcha When using the `@typechain/ethers-v6` target with ESM module resolution (e.g., in a Node.js project configured with `type: 'module'`), you must explicitly enable the `--node16-modules` flag or `node16Modules: true` in your configuration for correct output. This ensures proper ESM resolution for the generated types.
- breaking Breaking changes exist between `ethers-v5` and `ethers-v6` TypeChain targets due to significant API differences in Ethers.js. Always ensure that the TypeChain target (`@typechain/ethers-v5` or `@typechain/ethers-v6`) matches the Ethers.js version used in your project to avoid type mismatches and runtime errors.
- gotcha The core `typechain` package provides the generator logic, but framework-specific bindings and integration (e.g., for Hardhat, Truffle, Ethers.js) require installing additional 'target' packages. Failing to install the correct target will prevent TypeChain from generating usable types for your chosen environment.
Install
-
npm install typechain -
yarn add typechain -
pnpm add typechain
Imports
- GeneratedContract
import { MyContract } from '../typechain-types/contracts/MyContract' - Hardhat plugin enablement
require('@typechain/hardhat')import '@typechain/hardhat'
- runTypeChain
import { runTypeChain } from 'typechain'
Quickstart
import { HardhatUserConfig, task } from 'hardhat/config';
import '@nomicfoundation/hardhat-toolbox';
import '@typechain/hardhat'; // Import the Hardhat TypeChain plugin
const config: HardhatUserConfig = {
solidity: "0.8.20",
networks: {
hardhat: {
chainId: 1337, // Example local network ID
},
},
typechain: {
outDir: 'typechain-types', // Output directory for generated types
target: 'ethers-v6', // Specify the target library (e.g., ethers.js v6)
alwaysConsiderOverloadedFunctions: true,
},
};
// Example Hardhat task demonstrating usage of TypeChain generated types
task("deploy", "Deploys a sample contract").setAction(async (taskArgs, hre) => {
const [deployer] = await hre.ethers.getSigners();
console.log(
"Deploying contracts with the account:",
deployer.address
);
// Accessing a generated contract factory type (e.g., Greeter__factory)
// Ensure your contract is named 'Greeter.sol' in the 'contracts' directory
const GreeterFactory = await hre.ethers.getContractFactory("Greeter");
const greeter = await GreeterFactory.deploy("Hello, Hardhat!");
await greeter.waitForDeployment();
console.log(`Greeter deployed to ${greeter.target}`);
// Using type-safe method calls on the deployed contract instance
const message = await greeter.greet();
console.log("Contract message:", message);
});
export default config;
/*
// Example Solidity contract: contracts/Greeter.sol
// SPDX-License-Identifier: MIT
// pragma solidity ^0.8.20;
//
// contract Greeter {
// string private _greeting;
//
// constructor(string memory greeting_) {
// _greeting = greeting_;
// }
//
// function greet() public view returns (string memory) {
// return _greeting;
// }
//
// function setGreeting(string memory greeting_) public {
// _greeting = greeting_;
// }
// }
*/