如何为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
相关产品推荐
相关产品推荐

