如何在TypeScript条件类型中用值而非类型实现合法时间类型
实现合法时间字符串类型的TypeScript方案
当然可以通过条件类型结合字符转数值的方式,实现小时≤24、分钟≤60的合法时间校验,下面提供两种可行方案:
方案一:枚举合法前缀(简洁高效)
直接通过枚举合法的小时、分钟前缀组合,避免生成非法值:
// 单个数字字符类型 type Digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'; // 合法分钟:00-59,第一位限制为0-5 type Minute = `${'0' | '1' | '2' | '3' | '4' | '5'}${Digit}`; // 合法小时:00-23,或可选的24(用于24:00场景) type Hour = | `${'0' | '1'}${Digit}` // 00-19 | `2${'0' | '1' | '2' | '3'}` // 20-23 | '24'; // 根据需求决定是否保留 // 最终合法时间类型 type ValidTime = `${Hour}:${Minute}`;
方案二:条件类型结合数值判断(灵活通用)
如果需要通过数值比较来实现范围限制,可以先将字符转为数字类型,再用条件类型做校验:
// 单个数字字符转数值 type CharToNum<T extends Digit> = T extends '0' ? 0 : T extends '1' ? 1 : T extends '2' ? 2 : T extends '3' ? 3 : T extends '4' ? 4 : T extends '5' ? 5 : T extends '6' ? 6 : T extends '7' ? 7 : T extends '8' ? 8 : 9; // 两位数字符串转数值 type TwoDigitToNum<T extends `${Digit}${Digit}`> = CharToNum<T[0]> * 10 + CharToNum<T[1]>; // 校验小时是否≤24 type ValidHour<T extends string> = T extends `${Digit}${Digit}` | '24' ? TwoDigitToNum<T extends '24' ? '24' : T> extends infer N ? N extends number ? (N <= 24 ? T : never) : never : never : never; // 校验分钟是否≤59 type ValidMinute<T extends string> = T extends `${Digit}${Digit}` ? TwoDigitToNum<T> extends infer N ? N extends number ? (N <= 59 ? T : never) : never : never : never; // 最终合法时间类型 type ValidTime<T extends string> = T extends `${infer H}:${infer M}` ? ValidHour<H> extends H ? ValidMinute<M> extends M ? T : never : never : never;
方案对比
- 方案一:代码简洁,类型推导速度快,适合固定范围的时间校验场景,可读性强。
- 方案二:通过数值判断实现范围限制,逻辑更通用,可适配动态调整的数值范围需求,但类型推导复杂度略高。
内容的提问来源于stack exchange,提问作者rustyBucketBay
相关产品推荐
相关产品推荐

