type X<T>=T extends `${string}${'*('}${infer A}${')+'}${string}${'*('}${infer A}${')+'}${string}`?A:never
type Y=X<'g*(a12)+gggggg*(h23)+'> // 'a12' | 'h23'
type z=X<'g*(a12)+gggggg*(h23)+gggggg*(5hgf)+'> // 'a12' | 'h23' but without '5hgf'
我的目标是根据某种模式从字符串中提取所有文字。在上面的代码中,我想提取带有前缀
'*(
' 和后缀 ')+
' 的文字。因此,type Y = 'a12' | 'h23'
。
但问题是一个字符串可以有任意数量的匹配模式文字,我不知道如何让打字稿提取所有匹配的文字。
对于代码示例,Typescript 仅提取 2 个文字,因为我写了两次
${string}${'*('}${infer A}${')+'}
。如果我写 type z=X<'g*(a12)+gggggg*(h23)+gggggg*(5hgf)+'>
,我仍然得到 type Z = 'a12' | 'h23'
'。理想情况下,我应该得到type Z = 'a12' | 'h23'|''5hgf''
如何使打字稿“迭代”字符串以获取所有所需的文字?
谢谢!
没有“迭代”方法,但您可以使用等效的“递归”方法。如果你把它写成 tail-recursive 形式,那么它适用于相当长的字符串(如果你有的话)。这是一种方法:
type X<T extends string, A extends string = never> =
T extends `${string}${'*('}${infer U}${')+'}${infer R}` ?
X<R, A | U> : A;
我们仍在编写
X<T>
来通过模板文字类型
解析字符串,但现在有一个
accumulator类型参数
A
来跟踪我们已经收集的匹配的union。如果给定一个与您的模式匹配的字符串,则类型 U
将是第一个匹配部分,类型 R
将是字符串的其余部分。然后我们使用 X<R, A | U>
进行递归,将 U
添加到现有的 A
累加器中。否则没有匹配项,我们返回 A
。让我们测试一下:type Y = X<'g*(a12)+gggggg*(h23)+'>
// ^? type Y = "a12" | "h23"
type Z = X<'g*(a12)+gggggg*(h23)+gggggg*(5hgf)+'>
// ^? type Z = "a12" | "h23" | "5hgf"
看起来不错。
Playground 代码链接