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

TypeScript动态选属性时出现“This expression is not constructable”错误求助

问题解决:动态选择区块链网络时TransactionListener构造报错

问题原因

当前selectNetwork函数返回的是EvmChains | Bitcoin | Solana的联合类型,虽然三个模块都包含services.TransactionListener,但TypeScript检测到它们的构造函数签名存在不兼容差异(比如参数类型、内部实现不同),因此直接实例化时会抛出类型不兼容错误。

解决方案

方案1:类型断言(快速临时解决)

在实例化时通过类型断言明确告知TypeScript当前构造函数的可用签名:

import { selectNetwork, Keys } from './multiplechain'
const network = selectNetwork(data.providerConfig.code as Keys)
const provider = new network.Provider(data.providerConfig as any)
// 添加类型断言跳过联合类型检查
const listener = new (network.services.TransactionListener as new (type: string) => any)('COIN')

方案2:公共接口约束(规范类型安全方案)

定义统一接口约束所有区块链模块的结构,让TypeScript明确识别各模块的公共属性:

import * as Solana from '@multiplechain/solana/node'
import * as Bitcoin from '@multiplechain/bitcoin/node'
import * as EvmChains from '@multiplechain/evm-chains/node'

// 定义TransactionListener的公共构造接口(可根据实际参数调整)
interface TransactionListenerConstructor {
  new (type: 'COIN' | 'TOKEN'): unknown;
}

// 定义区块链模块的公共结构
interface BlockchainNetwork {
  Provider: new (config: any) => unknown;
  services: {
    TransactionListener: TransactionListenerConstructor;
  };
  types: {
    TransactionTypeEnum: {
      COIN: string;
      TOKEN: string;
    };
  };
}

export enum Type {
    COIN = Solana.types.TransactionTypeEnum.COIN,
    TOKEN = Solana.types.TransactionTypeEnum.TOKEN,
}

// 断言各模块符合公共接口
const networks: Record<Keys, BlockchainNetwork> = {
    evmchains: EvmChains as BlockchainNetwork,
    bitcoin: Bitcoin as BlockchainNetwork,
    solana: Solana as BlockchainNetwork,
}

export type Keys = keyof typeof networks

export const selectNetwork = (key: Keys): BlockchainNetwork => networks[key]

修改后selectNetwork返回统一的BlockchainNetwork类型,TypeScript可正确识别构造签名,直接实例化不会报错。

方案3:泛型函数(保留模块具体类型)

通过泛型让TypeScript推断出具体模块的类型,避免联合类型的兼容性问题:

// 修改selectNetwork为泛型函数
export const selectNetwork = <K extends Keys>(key: K): typeof networks[K] => networks[key]

调用时指定泛型参数:

import { selectNetwork, Keys } from './multiplechain'
const code = data.providerConfig.code as Keys
// 指定泛型参数让TypeScript推断具体模块类型
const network = selectNetwork<typeof code>(code)
const provider = new network.Provider(data.providerConfig as any)
const listener = new network.services.TransactionListener('COIN')

这种方式既能保留各模块的具体类型信息,又能解决联合类型的构造兼容问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 02:57:08