Hardhat中使用expectEvent遇never类型参数报错的解决方法
问题解决:Hardhat中expectEvent提示事件类型不匹配
问题背景
使用Hardhat调用合约方法:
const resp0 = await collateralPool.selfCloseExit(tokenShare0, true, TokenExitType.MINIMIZE_FEE_DEBT, "", { from: accounts[0] });
返回值类型为Truffle.TransactionResponse<never>,当用OpenZeppelin的expectEvent测试事件时:
expectEvent(resp0, "AgentRedemptionInCollateral", { _amountUBA: fassets0 });
TypeScript提示事件名AgentRedemptionInCollateral需要为never类型。
核心原因
你的猜测是对的:如果AgentRedemptionInCollateral事件是在collateralPool调用的另一个子合约中触发的,直接用collateralPool的交易响应检测该事件会触发类型错误——expectEvent默认会校验当前合约(collateralPool)的事件类型集合,而目标事件不在其中,TypeScript就会抛出类型不匹配的错误。另外,返回值的never类型也说明合约的TypeScript类型定义可能不完整或存在依赖冲突。
解决方法
1. 指定事件所属的合约实例
如果已知事件属于某个子合约(比如AgentContract),先获取该合约实例,然后在expectEvent中传入合约实例明确事件类型:
// 获取子合约实例 const agentContract = await AgentContract.deployed(); // 传入合约实例作为第二个参数 expectEvent(resp0, agentContract, "AgentRedemptionInCollateral", { _amountUBA: fassets0 });
2. 修复合约TypeScript类型定义
- 若使用TypeChain生成合约类型,重新执行类型生成命令:
npx typechain --target hardhat - 检查Hardhat配置,确保未混用Truffle和Hardhat的类型依赖(不要同时安装
@typechain/truffle-v5和@typechain/hardhat)。
3. 临时绕过类型检查(仅用于测试验证)
如果需要快速验证逻辑,可用类型断言临时绕过TypeScript校验:
expectEvent(resp0 as any, "AgentRedemptionInCollateral", { _amountUBA: fassets0 });
4. 手动遍历交易日志验证事件
直接从交易收据中查找对应事件,完全绕开类型问题:
const receipt = await resp0.wait(); const targetEvent = receipt.events?.find(event => event.event === "AgentRedemptionInCollateral"); expect(targetEvent).to.not.be.undefined; expect(targetEvent?.args._amountUBA).to.equal(fassets0);
内容的提问来源于stack exchange,提问作者kuco 23
相关产品推荐
相关产品推荐

