TypeScript bindings generator for Ethereum smart contracts that transforms ABI files into type-safe interfaces and classes
—
Tools for generating TypeScript code including barrel files, imports, and syntax utilities for TypeChain targets.
Generates barrel files with re-exports for all given paths (implements barrel pattern).
/**
* Generates barrel files with re-exports for all given paths
* @param paths - Array of file paths to create barrels for
* @param options - Configuration for barrel generation
* @returns Array of file descriptions for generated barrel files
*/
function createBarrelFiles(
paths: string[],
options: {
/** Whether to generate type-only exports */
typeOnly: boolean;
/** Optional postfix to add to export names */
postfix?: string;
/** Optional suffix to add to module imports */
moduleSuffix?: string;
}
): FileDescription[];
interface FileDescription {
/** File path for the generated barrel file */
path: string;
/** TypeScript content for the barrel file */
contents: string;
}Usage Example:
import { createBarrelFiles } from "typechain";
// Generate barrel files for contract bindings
const contractPaths = [
"./typechain-types/MyToken.ts",
"./typechain-types/MyNFT.ts",
"./typechain-types/factories/MyToken__factory.ts"
];
const barrelFiles = createBarrelFiles(contractPaths, {
typeOnly: false,
postfix: "__factory",
moduleSuffix: ".js"
});
// Result: barrel files with re-exports like:
// export { MyToken } from "./MyToken.js";
// export { MyToken__factory } from "./factories/MyToken__factory.js";Creates an identifier prefixing reserved words with underscore.
/**
* Creates an identifier prefixing reserved words with underscore
* Used for function parameters and tuple element names
* @param identifierName - Original identifier name
* @returns Safe identifier name for TypeScript
* @internal
*/
function createPositionalIdentifier(identifierName: string): string;Returns list of identifiers that are used in the source file.
/**
* Returns list of identifiers that are used in the source file
* @param identifiers - Array of potential identifiers to check
* @param sourceFile - TypeScript source code to scan
* @returns Array of identifiers actually used in the source
* @internal
*/
function getUsedIdentifiers(identifiers: string[], sourceFile: string): string[];Creates TypeScript import type declaration.
/**
* Creates TypeScript import type declaration
* @param identifiers - Array of type identifiers to import
* @param moduleSpecifier - Module path to import from
* @returns TypeScript import type statement
* @internal
*/
function createImportTypeDeclaration(identifiers: string[], moduleSpecifier: string): string;Creates import statements for identifiers actually used in source file.
/**
* Creates import statements for identifiers actually used in source file
* @param possibleImports - Map of module specifiers to available identifiers
* @param sourceFile - TypeScript source code to analyze
* @returns Generated import statements
* @internal
*/
function createImportsForUsedIdentifiers(
possibleImports: Record<ModuleSpecifier, Identifier[]>,
sourceFile: string
): string;
type ModuleSpecifier = string;
type Identifier = string;Converts valid directory name to valid variable name.
/**
* Converts valid directory name to valid variable name
* @param rawName - Directory name (e.g., "0directory-name")
* @returns Valid JavaScript identifier (e.g., "_0DirectoryName")
*/
function normalizeDirName(rawName: string): string;Usage Example:
import { normalizeDirName } from "typechain";
const normalized = normalizeDirName("0my-contract");
// Result: "_0MyContract"
const normalized2 = normalizeDirName("special-contracts");
// Result: "SpecialContracts"Function type for output transformers that process generated code.
/**
* Function type for output transformers
* @param output - Generated TypeScript code
* @param services - External services (fs, prettier, etc.)
* @param cfg - TypeChain configuration
* @returns Transformed output code
*/
type OutputTransformer = (output: string, services: Services, cfg: Config) => string;
interface Services {
fs: typeof fs;
prettier: typeof prettier;
mkdirp: typeof mkdirp;
}
interface Config {
cwd: string;
target: string;
outDir?: string;
prettier?: object;
filesToProcess: string[];
allFiles: string[];
inputDir: string;
flags: CodegenConfig;
}Array of output transformer functions applied to generated code.
/**
* Array of output transformer functions applied to generated code
* Transformers are applied in order to process and format output
*/
const outputTransformers: OutputTransformer[];Applies prettier formatting to generated TypeScript code.
/**
* Applies prettier formatting to generated TypeScript code
* Uses prettier configuration from project or default TypeScript settings
*/
const prettierOutputTransformer: OutputTransformer;Adds standard preamble to generated files.
/**
* Adds standard preamble to generated files
* Includes autogenerated comment, linting disables, optional @ts-nocheck
*/
const addPreambleOutputTransformer: OutputTransformer;Generated Preamble Example:
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
// @ts-nocheck (if cfg.flags.tsNocheck is true)
// Generated TypeScript bindings follow...While the template system is internal to target implementations, here's how code generation typically works:
// Example of how targets use the code generation utilities
import {
createBarrelFiles,
createImportsForUsedIdentifiers,
normalizeDirName
} from "typechain";
class EthersV5Target extends TypeChainTarget {
transformFile(file: FileDescription): FileDescription[] {
const contract = parse(extractAbi(file.contents), file.path);
// Generate main contract binding
const contractFile = {
path: `${contract.name}.ts`,
contents: this.generateContractBinding(contract)
};
// Generate factory
const factoryFile = {
path: `factories/${contract.name}__factory.ts`,
contents: this.generateFactory(contract)
};
return [contractFile, factoryFile];
}
afterRun(): FileDescription[] {
// Generate barrel files for all contracts
return createBarrelFiles(this.generatedFiles, {
typeOnly: false,
moduleSuffix: this.cfg.flags.node16Modules ? '.js' : undefined
});
}
}Functions for organizing generated files:
/**
* Generate appropriate file path for contract binding
* @param contract - Parsed contract object
* @param target - Target generator name
* @param options - Path generation options
* @returns Relative file path for the binding
*/
function generateContractFilePath(
contract: Contract,
target: string,
options?: { includeFactories?: boolean }
): string;
/**
* Generate appropriate file path for factory binding
* @param contract - Parsed contract object
* @param target - Target generator name
* @returns Relative file path for the factory
*/
function generateFactoryFilePath(contract: Contract, target: string): string;Generated code includes standard quality measures:
Typical structure of generated TypeScript files:
/* Autogenerated file. Do not edit manually. */
/* tslint:disable */
/* eslint-disable */
import type { BaseContract, BigNumber, Signer, utils } from "ethers";
export interface MyTokenInterface extends utils.Interface {
functions: {
"transfer(address,uint256)": FunctionFragment;
// ... other functions
};
getFunction(nameOrSignatureOrTopic: "transfer"): FunctionFragment;
// ... other methods
}
export interface MyToken extends BaseContract {
interface: MyTokenInterface;
transfer(to: string, value: BigNumber): Promise<ContractTransaction>;
// ... other methods
}Install with Tessl CLI
npx tessl i tessl/npm-typechain