ABIType: Ethereum ABI TypeScript Types
ABIType is a TypeScript-first library providing strict type definitions and utilities for Ethereum ABIs (Application Binary Interfaces) and EIP-712 Typed Data. It enables developers to achieve compile-time type-checking and inference for contract interactions without requiring external code generation tools. The current stable version is 1.2.4, with frequent patch and minor releases addressing bug fixes, performance improvements, and adding experimental features like named tuple support. Its primary differentiator is its deep integration with TypeScript's type system to convert ABI types (e.g., 'string') directly into TypeScript types (e.g., `string` or `0x${string}`) for enhanced developer experience, widely adopted by prominent libraries such as Wagmi and Viem. It also offers runtime validation capabilities for ABIs.
Common errors
-
Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'abitype' imported from /path/to/your/file.js
cause Attempting to import `abitype` using CommonJS `require()` syntax or running an ESM file in a CommonJS context.fixEnsure your Node.js project is configured for ESM (`"type": "module"` in `package.json` or `.mjs` extension) and use `import` statements. If you absolutely must use CommonJS, consider dynamic `import('abitype')` within an `async` function, but this is not the intended usage. -
Type '"uint256"' is not assignable to type '"string" | "number" | "boolean" | "null" | "undefined" | "bigint" | `0x${string}` | `0x${string}`[] | ...'.cause Mismatch between an ABI type string and the expected primitive TypeScript type. ABIType automatically converts ABI types (e.g., `'uint256'`) to their corresponding TypeScript primitive type (e.g., `bigint`).fixEnsure you are using the correct `AbiParametersToPrimitiveTypes` or similar utility to transform the ABI type string into its TypeScript equivalent before assigning or comparing. For example, `AbiParametersToPrimitiveTypes<['uint256']>['inputs']` would resolve to `[bigint]`. -
Property 'name' does not exist on type 'AbiParameter'.
cause Attempting to access a property that might not be present on a generic ABI type or an improperly typed ABI object. For example, a tuple type might not have a direct `name` property at its root.fixUse ABIType's specific type utilities like `ExtractAbiFunction` or `ExtractAbiEvent` to narrow down the type of an ABI item, which will then expose properties like `name`, `inputs`, or `outputs` with correct type safety. Ensure your ABI structure is valid according to the Solidity ABI specification.
Warnings
- breaking ABIType `v1.1.0` introduced support for Zod `v4`, broadening compatibility. Users migrating from older Zod versions (pre-v3.22) might experience issues if their `zod` peer dependency is not updated accordingly.
- gotcha The package is designed for ESM (ECMAScript Modules). Using CommonJS `require()` syntax directly might lead to 'Module not found' or incorrect type inference, especially for type-only imports.
- gotcha ABIType relies heavily on advanced TypeScript features. Ensure your `typescript` peer dependency meets the minimum requirement of `>=5.0.4` to avoid compilation errors related to type inference or declaration merging.
- gotcha Version `1.2.4` fixed a regex issue for Zod identifiers, preventing invalid identifiers (like those containing spaces or starting with numbers) from being accepted. While a fix, it might make previously 'accepted' but invalid ABIs now fail validation.
- gotcha Pre-defined ABIs (like `erc20Abi`) are located in the `abitype/abis` path, not directly from the main `abitype` export. Attempting to import them from the root might result in undefined symbols.
Install
-
npm install abitype -
yarn add abitype -
pnpm add abitype
Imports
- AbiParametersToPrimitiveTypes
import { AbiParametersToPrimitiveTypes } from 'abitype'import type { AbiParametersToPrimitiveTypes } from 'abitype' - ExtractAbiFunction
const ExtractAbiFunction = require('abitype').ExtractAbiFunctionimport type { ExtractAbiFunction } from 'abitype' - erc20Abi
import { erc20Abi } from 'abitype'import { erc20Abi } from 'abitype/abis' - parseAbi
import { parseAbi } from 'abitype/runtime'import { parseAbi } from 'abitype'
Quickstart
import type { AbiParametersToPrimitiveTypes, ExtractAbiFunction, ExtractAbiFunctionNames } from 'abitype';
import { erc20Abi, parseAbi } from 'abitype/abis';
// Example 1: Extracting function names from an ABI
type ViewFunctionNames = ExtractAbiFunctionNames<typeof erc20Abi, 'view'>;
// ^? type ViewFunctionNames = "symbol" | "name" | "allowance" | "balanceOf" | "decimals" | "totalSupply"
// Example 2: Getting primitive types for a function's inputs
type TransferInputTypes = AbiParametersToPrimitiveTypes<
ExtractAbiFunction<typeof erc20Abi, 'transfer'>['inputs']
>;
// ^? type TransferInputTypes = readonly [`0x${string}`, bigint]
// Example 3: Parsing a custom ABI string at runtime
const customAbi = parseAbi([
'function deposit() payable',
'event Deposit(address indexed user, uint256 amount)'
]);
console.log(customAbi[0].name); // 'deposit'
console.log(customAbi[1].type); // 'event'
// Example 4: Type-checking a variable against an ABI type
type MyCustomAbi = typeof customAbi;
// This will error if the structure doesn't match MyCustomAbi
const invalidAbi: MyCustomAbi = [
{
type: 'function',
name: 'withdraw',
inputs: [],
stateMutability: 'nonpayable',
outputs: []
}
];