如何实现TypeScript的数值范围类型numberRange
TypeScript实现区间约束泛型
numberRange 需求说明
实现泛型numberRange<Min extends number, Max extends number>,用于约束数值必须处于Min到Max的闭区间内。示例:
- 定义
one_to_nine = numberRange<1,9>,赋值5合法(✅),赋值10不合法(❎)
原实现问题分析
你尝试的代码如下:
type IsMore<A extends number, B extends number, L extends any[] = []> = A extends L['length'] ? false : B extends L['length'] ? true : IsMore<A, B, [...L, any]> type numRange<Min extends number, Max extends number> = true extends IsMore<infer U, Min> ? IsMore<Max, U> extends true ? U : never : never
该实现无效的核心问题是:true extends IsMore<infer U, Min>的写法逻辑错误。IsMore返回的是布尔类型,无法通过infer U反向推导出符合条件的数值类型——布尔值里不包含任何数值的类型信息,自然没法完成推导。
正确实现方案
方案一:生成区间联合类型
通过递归生成从Min到Max的所有数值联合类型,直接约束变量只能取区间内的值:
// 递归生成0到N的数值联合类型 type BuildNumberArray<N extends number, Arr extends any[] = []> = Arr['length'] extends N ? Arr['length'] : Arr['length'] | BuildNumberArray<N, [...Arr, any]>; // 生成Min到Max的区间类型:取0到Max的集合,排除0到Min-1的部分 type numberRange<Min extends number, Max extends number> = Exclude<BuildNumberArray<Max>, BuildNumberArray<Min>>;
测试验证:
type one_to_nine = numberRange<1,9>; const validNum: one_to_nine = 5; // ✅ 合法,无报错 const invalidNum: one_to_nine = 10; // ❌ 报错:类型“10”不能赋值给类型“1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9”
方案二:直接判断数值是否在区间内
如果需要更精准的类型判断(而非生成联合类型),可以写一个类型来直接验证数值是否处于区间:
// 判断N是否小于等于Target type IsLessOrEqual<N extends number, Target extends number, Arr extends any[] = []> = Arr['length'] extends N ? true : Arr['length'] extends Target ? false : IsLessOrEqual<N, Target, [...Arr, any]>; // 判断数值Num是否在Min到Max区间内 type IsInRange<Num extends number, Min extends number, Max extends number> = IsLessOrEqual<Min, Num> extends true ? IsLessOrEqual<Num, Max> extends true ? Num : never : never; // 定义区间类型 type one_to_nine<Num extends number> = IsInRange<Num, 1,9>;
测试验证:
const valid: one_to_nine<5> = 5; // ✅ 合法 const invalid: one_to_nine<10> = 10; // ❌ 报错:类型“10”不能赋值给类型“never”
内容的提问来源于stack exchange,提问作者jimin hu
相关产品推荐
相关产品推荐

