TypeScript中如何声明指定长度范围的数组类型?有更简洁写法吗?
结论
可以实现,你可以通过封装通用的TS工具类型达到和预期几乎一致的简写效果,最终生成的类型和你手动写的联合元组类型完全等价。
实现代码
先定义两个通用工具类型:
// 构造固定长度的同类型元组 type BuildTuple<Length extends number, ElementType, Result extends ElementType[] = []> = Result['length'] extends Length ? Result : BuildTuple<Length, ElementType, [...Result, ElementType]>; // 构造长度在[Min, Max]区间的同类型元组联合 type RangeTuple<Min extends number, Max extends number, ElementType = number> = Min extends Max ? BuildTuple<Max, ElementType> : BuildTuple<Min, ElementType> | RangeTuple<Min + 1, Max, ElementType>;
定义完成后你的业务类型就可以简化为:
export type Type = RangeTuple<1, 4, number>;
如果你的业务场景都是number类型的元组,还可以再封装一层进一步简化,完全匹配你想要的简写效果:
type NumberRangeTuple<Min extends number, Max extends number> = RangeTuple<Min, Max, number>; // 效果和你预期的`number[1,4]`基本一致 export type Type = NumberRangeTuple<1, 4>;
效果验证
上述定义的Type和你手动写的联合类型完全等价,测试用例如下:
const t1: Type = [1]; // 合法 const t2: Type = [1, 2]; // 合法 const t3: Type = [1, 2, 3]; // 合法 const t4: Type = [1, 2, 3, 4]; // 合法 const t5: Type = []; // 编译报错:长度不符合要求 const t6: Type = [1, 2, 3, 4, 5]; // 编译报错:长度不符合要求
注意事项
- 依赖TS 4.1及以上版本,用到了递归条件类型、剩余元组等新语法特性
- 长度区间范围不要过大,默认TS递归深度限制为20,要是需要更长的区间可以调整
tsconfig.json中的recursionLimit配置
内容的提问来源于stack exchange,提问作者ZhenyaUsenko
相关产品推荐
相关产品推荐

