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

如何为TypeScript中递归处理BN的函数正确标注类型?

解决方案:用递归泛型实现精确类型映射

要解决这个问题,核心是让TypeScript能递归追踪输入类型到输出类型的转换关系——把所有BN类型替换为string,同时保留原始类型和数组的嵌套结构。

步骤1:定义递归转换类型

先声明一个泛型类型StringifyBN<T>,它会递归地将输入类型中的BN替换为string:

type StringifyBN<T> = 
  T extends BN ? string :
  T extends Array<infer U> ? StringifyBN<U>[] :
  T;
  • 第一分支:如果T是BN类型,转换后为string
  • 第二分支:如果T是数组,递归处理数组的每个元素,再返回新数组类型
  • 第三分支:其他原始类型(number/string/boolean)保持不变

步骤2:完善isBN的类型守卫

确保isBN函数是类型谓词函数,让TypeScript能在条件分支中正确缩小类型:

function isBN(value: unknown): value is BN {
  // 填入bn.js的类型判断逻辑,比如:
  return typeof value === 'object' && value !== null && 'constructor' in value && value.constructor.name === 'BN';
}

步骤3:实现带泛型的转换函数

利用上面的泛型类型,给函数加上精确的输入输出类型标注:

function stringifyBN<T>(value: T): StringifyBN<T> {
  if (isBN(value)) {
    return value.toString() as StringifyBN<T>;
  }

  if (Array.isArray(value)) {
    return value.map(v => stringifyBN(v)) as StringifyBN<T>;
  }

  return value as StringifyBN<T>;
}

为什么之前的写法报错?

你之前用的联合类型number | string | boolean | BN | ...[]无法处理嵌套数组(比如BN[][]),而且map返回的数组类型是混合元素的数组,和你声明的返回类型(单一类型的数组或原始类型)不匹配。递归泛型则能动态生成对应嵌套结构的输出类型,完美解决这个问题。

类型验证示例

// 测试用例
const input: (number | BN | boolean[])[] = [123, new BN(456), [true, new BN(789)]];
const output = stringifyBN(input);
// output的类型会被推导为:(number | string | boolean[])[]
// 其中所有BN都被替换成了string

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 12:01:02