Viem从0.8.x升级到1.4.1后丢失返回结果属性访问能力
问题
将Viem从0.8.x版本迁移至1.4.1版本后,调用合约函数getTreasuryAndPhilantrophyBalanceInUSD时,返回结果仅为数组形式[902828817075004553524n, 0n],无法像之前那样通过treasuryBalance、philantrophyBalance等命名属性访问,原有TypeScript代码因此失效。
相关ABI定义:
{ inputs: [], name: 'getTreasuryAndPhilantrophyBalanceInUSD', outputs: [ { internalType: 'uint256', name: 'treasuryBalance', type: 'uint256', }, { internalType: 'uint256', name: 'philantrophyBalance', type: 'uint256', }, ], stateMutability: 'view', type: 'function', },
ABI导出代码:
import { Abi } from 'viem'; export const abiTest: Abi = [...] as const;
readContract调用代码:
const resultRead = await client.readContract({ abi: abiCfaPeriphery, address: '...' as Address, functionName: 'getTreasuryAndPhilantrophyBalanceInUSD', }); console.log('Result Read: ', resultRead);
已查阅Viem类型推断文档及TypeScript const断言相关资料,仍未找到解决办法,求排查操作问题。
解决方案
问题根源是ABI的类型声明覆盖了字面量类型信息:你给ABI显式标注了Abi类型,这会抹掉as const断言带来的精确类型细节,导致Viem无法从ABI中推导带命名属性的返回类型。
- 修改ABI导出代码:去掉显式的
Abi类型标注,仅保留as const断言:
import { Abi } from 'viem'; // 移除: Abi 类型标注,让TypeScript保留完整的字面量类型 export const abiTest = [...] as const;
修改后,Viem会自动基于ABI的字面量类型,为readContract的返回值生成包含treasuryBalance、philantrophyBalance命名属性的类型,你就能像之前一样通过属性名访问返回值。
- 若需显式标注类型:可以通过以下方式保留字面量类型:
const abiTestRaw = [...] as const; export const abiTest: typeof abiTestRaw = abiTestRaw;
或者直接依赖Viem的自动类型推导,无需手动标注Abi类型。
另外要确认,调用readContract时传入的abi参数是修改后保留了字面量类型的ABI对象,而非被类型抹除的版本。
内容的提问来源于stack exchange,提问作者Raúl
相关产品推荐
相关产品推荐

