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

TypeScript中如何动态类型化ABI的networkId键而非固定值?

TypeScript动态networkId适配artifact.networks的类型解决方案

问题根源

web3.eth.net.getId()返回的是number类型,但artifact的networks对象键通常是字符串类型的网络ID(比如"5777"),而且TypeScript无法确认动态获取的networkId一定是networks的合法键,因此触发类型检查报错。

可行解决方案

方案1:类型断言+字符串转换

将number类型的networkId转为字符串,同时用keyof typeof自动提取networks的合法键类型,通过断言告诉TypeScript该键合法:

const networkId = await web3.eth.net.getId();
// 转为字符串并断言为artifact.networks的合法键
const networkKey = networkId.toString() as keyof typeof artifact.networks;

DeluxerContract = new web3.eth.Contract(
  artifact.abi,
  artifact.networks[networkKey].address
);

方案2:给Artifact定义精确类型

如果是自定义的Artifact类型,直接扩展其networks的键类型,支持字符串/数字或已知网络ID联合类型:

// 支持任意字符串/数字键的版本
type Artifact = {
  abi: any; // 建议替换为TypeChain生成的具体ABI类型
  networks: Record<string | number, { address: string }>;
};

// 已知固定网络ID的版本(更严格)
type KnownNetworkIds = "5777" | "1" | "5"; // 按需添加
type Artifact = {
  abi: any;
  networks: Record<KnownNetworkIds, { address: string }>;
};

// 使用时转换并断言
const networkId = await web3.eth.net.getId();
DeluxerContract = new web3.eth.Contract(
  artifact.abi,
  artifact.networks[networkId.toString() as KnownNetworkIds].address
);

方案3:类型守卫+异常处理(最安全)

通过in操作符做类型守卫,检查networkId是否存在于networks中,同时处理不存在的异常情况:

const networkId = await web3.eth.net.getId();
const networkKey = networkId.toString();

// TypeScript会自动识别if块内networkKey为合法键
if (networkKey in artifact.networks) {
  DeluxerContract = new web3.eth.Contract(
    artifact.abi,
    artifact.networks[networkKey].address
  );
} else {
  throw new Error(`当前网络${networkId}未在artifact配置中找到`);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 05:33:15