如何在TypeScript中定义可变长度的正则匹配字符串类型及十六进制字符串类型?
TypeScript 可变长度正则匹配字符串与ByteString类型实现
一、可变长度的正则匹配字符串类型
在TypeScript中,固定长度的正则匹配字符串可以直接用模板字面量实现,但可变长度的需要借助递归条件类型实现无限扩展,以下是常见场景的示例:
1. 匹配任意长度的小写字母字符串
先定义单个小写字母的联合类型,再通过递归拼接实现任意长度:
type LowercaseLetter = 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z'; // 允许空字符串,若需禁止空字符串,将''替换为LowercaseLetter type LowercaseString = '' | `${LowercaseLetter}${LowercaseString}`; // 测试 let validStr: LowercaseString = 'typescript'; // ✅ 合法 let invalidStr: LowercaseString = 'TypeScript'; // ❌ 包含大写字母,不合法
2. 匹配包含数字/大小写字母的任意长度字符串
针对更复杂的字符范围,通过条件类型递归校验每一位字符:
type AlphanumericChar = | '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z'; type AlphanumericString = '' | `${AlphanumericChar}${AlphanumericString}`; // 测试 let validAlphaNum: AlphanumericString = 'TS2024'; // ✅ 合法 let invalidAlphaNum: AlphanumericString = 'TS@2024'; // ❌ 包含特殊字符,不合法
如果需要更贴近正则语法的写法,TypeScript 4.4+支持在条件类型中结合模板字面量的类型推断:
type MatchAlphanumeric<T extends string> = T extends `${infer Char}${infer Rest}` ? Char extends AlphanumericChar ? MatchAlphanumeric<Rest> : never : T; // 使用时直接约束字符串类型 type ValidAlphanumeric<T extends string> = MatchAlphanumeric<T>; let testStr: ValidAlphanumeric<'abc123'> = 'abc123'; // ✅ 合法 // let testStr2: ValidAlphanumeric<'abc!123'> = 'abc!123'; // ❌ 报错
二、ByteString类型实现(偶数长度十六进制字符串)
要实现**仅允许偶数长度、且每一位都是十六进制字符(0-9/a-f/A-F)**的类型,通过递归类型即可支持任意偶数长度:
1. 定义单个十六进制字符的联合类型
type HexChar = | '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'A' | 'B' | 'C' | 'D' | 'E' | 'F';
2. 递归构建偶数长度的ByteString类型
核心思路:字符串要么是空字符串,要么是两个十六进制字符加上另一个ByteString(保证总长度始终为偶数):
// 若需禁止空字符串,将''替换为`${HexChar}${HexChar}` type ByteString = '' | `${HexChar}${HexChar}${ByteString}`; // 测试示例 let str: ByteString = "f1afe3"; // ✅ 合法(长度6,偶数,全十六进制) // let str1: ByteString = "fa1"; // ❌ 报错(长度3,奇数) // let str2: ByteString = "hello"; // ❌ 报错(包含非十六进制字符) let str3: ByteString = "ffeeaa3300"; // ✅ 合法(长度10,偶数,全十六进制)
内容的提问来源于stack exchange,提问作者sinoTrinity
相关产品推荐
相关产品推荐

