You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用ethers v6与hardhat-toolbox v3时FundMe类型转换报错求助

问题:Hardhat Toolbox v3(Ethers v6)下Typechain类型转换报错解决方案

问题背景

我正在使用基于Ethers v6的@nomicfoundation/hardhat-toolbox v3.0.0版本,以下代码在搭配Ethers v5的@nomicfoundation/hardhat-toolbox v2.0.2中可正常运行:

import { FundMe } from "./../../typechain-types"

describe("FundMe", async () => {
    let fundMe: FundMe

    beforeEach(async () => {
        const fundMeContract = await deployments.get("FundMe")
        fundMe = (await ethers.getContractAt(
            fundMeContract.abi,
            fundMeContract.address
        )) as FundMe
    })
})

升级新版本后,出现如下TypeScript错误:

Conversion of type 'Contract' to type 'FundMe' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
  Type 'BaseContract & Omit<ContractInterface, keyof BaseContract>' is missing the following properties from type 'FundMe': attach, deployed, functions, MINIMUM_USD, and 9 more.

尝试添加类型参数时,报错Expected 0 type arguments, but got 1.ts(2558);直接赋值仍提示类型缺失属性。代码可正常运行,但VSCode始终显示错误,需要在不使用any类型的情况下让TypeScript正常识别。


解决方案

方法一:使用Typechain生成的工厂类(推荐)

Ethers v6和Hardhat Toolbox v3中,Typechain会为每个合约生成对应的工厂类(后缀为__factory),通过工厂类的connect方法可以直接获取类型匹配的合约实例,无需强制类型转换:

  1. 导入Typechain生成的合约类型和工厂类:
import { FundMe, FundMe__factory } from "./../../typechain-types";
import { ethers } from "hardhat";
  1. 修改测试代码中的合约实例获取逻辑:
describe("FundMe", async () => {
    let fundMe: FundMe;

    beforeEach(async () => {
        const fundMeContract = await deployments.get("FundMe");
        // 使用工厂类连接到已部署的合约地址,自动匹配类型
        // 若需要使用指定签名者,替换ethers.provider为对应的signer即可
        fundMe = FundMe__factory.connect(fundMeContract.address, ethers.provider);
    });
});

原理说明:
Ethers v6的BaseContract结构与v5的Contract差异较大,Typechain在v3版本中生成的合约类型是基于Ethers v6的BaseContract扩展的,工厂类的connect方法会直接返回完全匹配的合约类型实例,TypeScript可以完美识别所有合约方法和属性。

方法二:通过unknown中转强制类型转换(不推荐)

如果暂时不想修改为工厂类写法,可以先将ethers.getContractAt的返回值转为unknown,再转为目标合约类型,绕开TypeScript的类型检查:

fundMe = (await ethers.getContractAt(fundMeContract.abi, fundMeContract.address)) as unknown as FundMe;

这种方法虽然能消除报错,但不如工厂类方式类型安全,不推荐长期使用。


内容的提问来源于stack exchange,提问作者6be709c0

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 18:22:52