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

如何让TypeScript的IntRange类型支持负数范围?

解决TypeScript IntRange支持负数范围的问题

原有的IntRange类型依赖Enumerate通过数组长度递归生成整数,但数组长度只能是非负数,遇到起始值为负数的情况时,递归永远无法触发终止条件,直接导致TS2589: Type instantiation is excessively deep and possibly infinite错误。

下面是修改后的实现,能支持包含负数的整数范围:

修改后的类型代码

// 生成从0到绝对值N-1的整数枚举
type EnumerateAbs<N extends number, Acc extends number[] = []> = 
  Acc['length'] extends N ? Acc[number] : EnumerateAbs<N, [...Acc, Acc['length']]>;

// 计算两个数的绝对值差
type AbsDiff<A extends number, B extends number> = 
  `${A}` extends `-${infer NumA extends number}` 
    ? `${B}` extends `-${infer NumB extends number}` 
      ? NumA extends NumB ? 0 : NumA > NumB ? NumA - NumB : NumB - NumA
      : NumA + B
    : `${B}` extends `-${infer NumB extends number}` 
      ? A + NumB
      : A > B ? A - B : B - A;

// 支持正负范围的IntRange
type IntRange<F extends number, T extends number> = 
  F extends T ? F :
  F extends infer FNum extends number 
    ? T extends infer TNum extends number
      ? FNum < TNum
        ? EnumerateAbs<AbsDiff<FNum, TNum>> extends infer R extends number
          ? R + FNum
          : never
        : EnumerateAbs<AbsDiff<FNum, TNum>> extends infer R extends number
          ? TNum + R
          : never
      : never
    : never;

关键逻辑说明

  1. EnumerateAbs:只负责生成非负的整数枚举,避开负数导致的递归死循环;
  2. AbsDiff:通过模板字符串解析数字符号,计算两个数之间的绝对值差,确定需要生成的整数数量;
  3. IntRange核心:
    • 如果起始值小于结束值,就从起始值开始,累加EnumerateAbs生成的非负数,得到正向范围;
    • 如果起始值大于结束值,就从结束值开始累加,得到反向范围;
    • 处理起始值等于结束值的边界情况,直接返回该数值。

测试用例

// 正整数范围:25 | 26 | 27 | 28 | 29
type PositiveRange = IntRange<25, 30>;
// 包含负数的范围:-25 | -24 | ... | 3 | 4
type NegativeIncludedRange = IntRange<-25, 5>;
// 反向范围:-5 | -4 | ... | 8 | 9
type ReverseRange = IntRange<10, -5>;

内容的提问来源于stack exchange,提问作者Tyler V.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 05:32:37