使用@usedapp与@ethersproject/contracts调用智能合约时出现异常类型不兼容错误
这个问题我之前也碰到过!本质上是依赖版本冲突导致的TypeScript类型不兼容——你的项目根目录安装的@ethersproject/contracts和@usedapp/core内部依赖的@ethersproject/contracts版本不一致,TypeScript会把它们当成完全不同的类型(哪怕名字一模一样),所以才会报这种看起来莫名其妙的类型不匹配错误。
具体解决方案
1. 强制统一依赖版本(推荐)
通过包管理器的"强制解析"功能,让@usedapp/core使用你项目根目录安装的ethers版本,避免双份依赖:
如果你用Yarn,在
package.json里添加resolutions字段:"resolutions": { "@ethersproject/contracts": "^5.7.0" // 替换成你项目里实际安装的版本 }如果你用npm 8+,在
package.json里添加overrides字段:"overrides": { "@ethersproject/contracts": "^5.7.0" }
添加后,重新执行yarn install或npm install,让包管理器重新处理依赖树。
2. 手动统一版本
先查看你项目根目录package.json中@ethersproject/contracts的版本,然后安装与该版本兼容的@usedapp/core,或者升级@usedapp/core到支持你当前ethers版本的最新版。
比如你当前用的是ethers v5.x,确保@usedapp/core的版本也是基于v5的(注意@usedapp/core v3+开始支持ethers v6,如果你用v6要对应升级)。
3. 临时类型断言(不推荐)
如果只是想快速绕过类型检查,可以用类型断言把合约实例转为any,但这样会失去TypeScript的类型安全:
const { send: approveErc20Send, state: approveAndStakeErc20State } = useContractFunction(erc20Contract as any, "approve", { transactionName: "Approve ERC20 transfer", })
为什么会出现这个错误?
TypeScript对模块的类型判断是基于文件路径的,@usedapp/core/node_modules/@ethersproject/contracts和你项目根目录的node_modules/@ethersproject/contracts是两个不同的路径,哪怕里面的类型定义代码完全一样,TypeScript也会认为它们是不同的类型,自然就会报类型不兼容的错误了。
内容的提问来源于stack exchange,提问作者Cromewar

