531. 字符串转联合类型
大约 2 分钟
531. 字符串转联合类型
题目
实现 StringToUnion 类型。接收一个字符串参数,输出该字符串所有字符组成的联合类型。
type Test = "123"
type Result = StringToUnion<Test> // 期望得到 "1" | "2" | "3"解答
type StringToUnion<S extends string> =
S extends `${infer First}${infer Rest}`
? First | StringToUnion<Rest>
: never深入解析
原理剖析
这个解法利用 TypeScript 的模板字面量类型和条件类型,递归地将字符串分解为单个字符:
模式匹配:
S extends \{infer Rest}`使用模板字面量推断,提取第一个字符(First)和剩余字符串(Rest`)。构建联合类型:每次递归,通过
First | StringToUnion<Rest>将First加入联合类型。递归终止:当
S为空字符串时,模式匹配失败,返回never。由于T | never = T,递归干净地结束。
推演示例
以 StringToUnion<"abc"> 为例:
StringToUnion<"abc">
= "a" | StringToUnion<"bc">
= "a" | "b" | StringToUnion<"c">
= "a" | "b" | "c" | StringToUnion<"">
= "a" | "b" | "c" | never
= "a" | "b" | "c"为什么 infer 能精确匹配单个字符
当对字符串使用 ${infer First}${infer Rest} 时:
- TypeScript 从左边贪婪匹配,所以
First始终捕获恰好一个字符 Rest捕获剩余所有内容(包括空字符串)
边界情况
type Empty = StringToUnion<""> // never
type Single = StringToUnion<"x"> // "x"
type Spaces = StringToUnion<"a b"> // "a" | " " | "b"核心要点
模板字面量推断:
${infer X}${infer Y}是 TypeScript 类型系统中字符串分解的标准模式。递归构建联合类型:用
X | RecursiveType<Rest>递归构建联合类型是处理序列转换的常见套路。never的幺元性质:在联合类型中,never是幺元——加上它不改变结果,非常适合作为递归的终止条件。字符级操作:这个模式是很多字符串操作类型的基础,如
Split、Join和字符过滤等。
