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''

如何使打字脚本"重写"字符串以获得所有所需的文字?

谢谢!

推荐答案

对此没有iterative方法,但您可以使用等效的recursive方法.如果您将其写成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>来通过template literal types解析字符串,但现在有一个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 link to code

Typescript相关问答推荐

类型脚本:类型是通用的,只能索引以供阅读.(2862)"

类型脚本接口索引签名

泛型和数组:为什么我最终使用了`泛型T []`而不是`泛型T []`?<><>

仅针对某些状态代码重试HTTP请求

如何以Angular 形式显示验证错误消息

APIslice-CreateAPI的RTK打字错误

TypeScrip-将<;A、B、C和>之一转换为联合A|B|C

了解类型规则中的关键字

参数属性类型定义的REACT-RUTER-DOM中的加载器属性错误

如何通过TypeScrip中的函数防止映射类型中未能通过复杂推理的any值

防止重复使用 Select 器重新渲染

使用TypeScrip的类型继承

编译TypeScrip项目的一部分导致错误

对象类型的TypeScrip隐式索引签名

Typescript 中相同类型的不同结果

具有匹配功能的TS通用事件处理程序

无法缩小深度嵌套对象props 的范围

如何避免TS2322;类型any不可分配给类型never;使用索引访问时

断言同级为true或抛出错误的Typescript函数

对象只能使用 Typescript 中另一个对象的键