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

TypeScript报错求助:Operator '-'无法应用于bigint与number类型

解决TypeScript报错:Operator '-' cannot be applied to types 'bigint' and 'number'

问题原因

Web3.js的getBlockNumber()方法返回的是bigint类型,而你代码中的this.asyncHeight是number类型。TypeScript不允许bigint和number直接进行算术运算(加减乘除),所以currentBlockNumber - 2会触发类型错误,同时startBlock + 99 > currentBlockNumber也存在number与bigint混合比较的隐患。

解决方案(两种可选)

方案1:统一使用bigint类型(更严谨,适配Web3的返回类型)

将所有参与运算的number值转为bigint,保持类型一致:

修改代码中的关键行:

async startBlockEvent() {
    let success = true
    schedule.scheduleJob("*/10 * * * * *", async () => {
        try {
            const provieder = new Web3(Config[this.chainId].prc)
            // 保持currentBlockNumber为bigint类型
            let currentBlockNumber = await provieder.eth.getBlockNumber()
            // 将this.asyncHeight转为bigint后再运算
            if (currentBlockNumber > BigInt(this.asyncHeight) + 3n && success) {
                success = false
                // 转为bigint计算startBlock
                let startBlock = BigInt(this.asyncHeight) + 1n
                // 所有数字字面量用bigint(加n后缀)
                let endBlock = startBlock + 99n > currentBlockNumber ? currentBlockNumber - 2n : startBlock + 99n
                try {
                    // 若batchGetBlock期望number参数,需转成Number(startBlock)、Number(endBlock)
                    let result = await this.blockTx.batchGetBlock(Number(startBlock), Number(endBlock), provieder)
                    let deployCollection = await this.insertCollection(result.collections)
                    let updateCollection = await this.updateCollection(result.updateCollections)
                    let updateHolder = await this.updateHolder(result.holders)
                    let insertTransfer = await this.insertTransfer(result.orders)
                    let updateDeposit = await this.updateDepositEvent(result.depositEvents)
                    let insertBlockHash = await this.insertBlockHash(result.blockHashs)
                    if (deployCollection && updateCollection && updateHolder && insertTransfer && updateDeposit && insertBlockHash) {
                        // 若this.asyncHeight定义为number类型,转成Number(endBlock)赋值
                        this.asyncHeight = Number(endBlock)
                        let updateConfig = this.sqlConfig ? this.sqlConfig : { chainId: this.chainId, asyncHeight: 0 }
                        updateConfig.asyncHeight = Number(endBlock)
                        this.sqlConfig = updateConfig
                        await this.Db.update("config", updateConfig)
                        console.log(`sync ${endBlock},deploy ${result.collections.length},mint ${result.mints.length} ,update collection ${result.updateCollections.length},wallet ${result.holders.length},request time ${result.requestTime} ms,handler data time ${result.handleDataTime} ms,validate block ${result.blockHashs.length}`)
                    }
                    success = true
                } catch (error) {
                    console.log(error)
                    success = true
                }
            }
        } catch (error) {
            success = true
        }
    })
}

方案2:将bigint转为number(简单直接,适合区块号不超过2^53的场景)

以太坊当前区块号远小于JS number的最大值(2^53),可以安全转换:

修改getBlockNumber的结果处理:

// 将返回的bigint转为number
let currentBlockNumber = Number(await provieder.eth.getBlockNumber())

之后原代码的运算逻辑无需修改,所有变量都为number类型,类型错误会自动消失。

注意事项

  • 如果项目中Web3方法返回的bigint较多,推荐用方案1,避免后续频繁类型转换
  • 若batchGetBlock方法要求参数为number类型,方案1中需要将bigint转为number传入

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 19:40:09