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

TypeScript中BigNumber数组转普通数字遇报错的技术问询

Ethers.js中批量转换BigNumber数组的问题解决

问题场景

有一个包含BigNumber类型字段的对象arr,结构如下:

{
   size: BigNumber { value: '2' },
   pricePerDay: [ BigNumber { value: '103897429' }, BigNumber { value: '103827546' } ],
   unixDate: [ BigNumber { value: '1670268628' }, BigNumber { value: '1670268634' } ]
}

单个BigNumber用toNumber()可以正常转换,但直接对数组调用toNumber()会报错;用map批量转换时,遇到超过JavaScript安全整数范围的值会触发溢出错误。

错误原因分析

  1. 数组调用toNumber报错:pricePerDay和unixDate是数组,不是单个BigNumber实例,没有toNumber()方法,必须遍历数组逐个转换元素。
  2. 溢出错误:JavaScript的Number类型最大安全整数是2^53 - 1(约9e15),当BigNumber的值超过这个范围时,toNumber()会丢失精度并抛出溢出错误。

解决方案

1. 修复数组转换的基本逻辑

先修正代码里的语法错误和逻辑错误:

  • 函数定义缺少闭合括号
  • 应用转换时newArr未初始化,且unixDate错误传入了arr.pricePerDay

正确的数组转换函数:

function arrayBigNumberToNumber(arr: BigNumber[]): number[] {
    return arr.map(element => element.toNumber());
}

// 应用转换(原对象只读,需创建新对象)
const newObj = {
    size: arr.size.toNumber(),
    pricePerDay: arrayBigNumberToNumber(arr.pricePerDay),
    unixDate: arrayBigNumberToNumber(arr.unixDate)
};

2. 处理溢出问题

如果BigNumber值可能超过JavaScript安全整数范围,推荐以下两种方式:

方式一:转换为字符串

如果不需要进行数值计算,直接用toString()转为字符串避免溢出:

function arrayBigNumberToString(arr: BigNumber[]): string[] {
    return arr.map(element => element.toString());
}

const newObj = {
    size: arr.size.toString(),
    pricePerDay: arrayBigNumberToString(arr.pricePerDay),
    unixDate: arrayBigNumberToString(arr.unixDate)
};

方式二:转换为BigInt(ES2020+支持)

如果需要进行大整数运算,用toBigInt()转为原生BigInt类型:

function arrayBigNumberToBigInt(arr: BigNumber[]): bigint[] {
    return arr.map(element => element.toBigInt());
}

const newObj = {
    size: arr.size.toBigInt(),
    pricePerDay: arrayBigNumberToBigInt(arr.pricePerDay),
    unixDate: arrayBigNumberToBigInt(arr.unixDate)
};

方式三:按业务单位格式化

如果是以太坊的 wei 等单位,用formatUnits()转换为可读的数值字符串:

import { formatUnits } from "ethers/lib/utils";

function formatBigNumberArray(arr: BigNumber[], unit: string = "wei"): string[] {
    return arr.map(element => formatUnits(element, unit));
}

// 示例:转换为以太币单位
const newObj = {
    size: arr.size.toNumber(),
    pricePerDay: formatBigNumberArray(arr.pricePerDay, "ether"),
    unixDate: arrayBigNumberToNumber(arr.unixDate) // 时间戳一般不会超过安全整数
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 20:10:25