React+TypeScript中优雅实现指定范围数字的组件Props校验
优雅实现TypeScript中0-24整数的Props类型校验
方案1:用递归类型工具生成范围联合类型
TypeScript没有原生的数字范围类型,但可以通过递归类型工具自动生成0到24的整数联合类型,无需手动罗列所有数字:
// 生成0到N-1的整数联合类型 type Enumerate<N extends number, Acc extends number[] = []> = Acc['length'] extends N ? Acc[number] : Enumerate<N, [...Acc, Acc['length']]>; // 生成从F到T-1的整数联合类型 type Range<F extends number, T extends number> = Exclude<Enumerate<T>, Enumerate<F>> | F; export interface ComponentProps { title: string; value: Range<0, 25>; // 传25是因为Enumerate<25>生成0-24,最终得到0到24的联合类型 }
这个工具类型可复用,后续调整范围只需修改Range的参数即可。
方案2:运行时校验+类型守卫(兼顾编译与运行时)
如果组件可能接收外部传入的参数,仅靠编译期类型检查不够,这时可以用类型守卫配合运行时校验,既保证类型安全又能拦截非法值:
export interface ComponentProps { title: string; value: number; } // 类型守卫函数,校验值是否为0-24之间的整数 function isValueInRange(value: number): value is 0 | 1 | 2 | ... | 24 { return value >= 0 && value <= 24 && Number.isInteger(value); } // 组件内部使用 function MyComponent(props: ComponentProps) { if (!isValueInRange(props.value)) { throw new Error('value必须是0到24之间的整数'); } // 此时props.value会被TS推断为0-24的整数类型 }
类型守卫里的联合类型无需手动写全,TS会自动识别符合条件的类型范围。
方案3:用数组生成联合类型(直观简洁)
通过生成包含0-24的只读数组,再提取数组元素的类型,写法直观易懂:
// 生成包含0到24的只读数组 const validValues = Array.from({ length: 25 }, (_, index) => index) as const; // 提取数组元素的类型,即0-24的联合类型 type ValidValue = typeof validValues[number]; export interface ComponentProps { title: string; value: ValidValue; }
这种方式代码量少、逻辑清晰,适合范围固定且无需频繁修改的场景。
内容的提问来源于stack exchange,提问作者Igal
相关产品推荐
相关产品推荐

