How to extract multiple literals from a string using Typescript

type Extracted<T> = T extends `${string}${'*('}${infer A}${')+'}${string}${'*('}${infer A}${')+'}${string}` ? A : never

type Result1 = Extracted<'g*(a12)+gggggg*(h23)+'> // 'a12' | 'h23'

type Result2 = Extracted<'g*(a12)+gggggg*(h23)+gggggg*(5hgf)+'> // 'a12' | 'h23' but without '5hgf'

The goal is to extract all literals from a string with a specific pattern. In the given code, I want to extract literals that start with '*(' and end with ')+''. Therefore, type Result1 = 'a12' | 'h23'.

The challenge lies in handling situations where a string can have multiple matched-pattern-literals, and it's unclear how to make typescript extract all of them.

In the provided example, Typescript only extracts two literals because the pattern is repeated twice:

${string}${'*('}${infer A}${')+'}
. Even with
 type z=Extracted<'g*(a12)+gggggg*(h23)+gggggg*(5hgf)'+>
, the result remains as type Result2 = 'a12' | 'h23'. Ideally, the output should include '5hgf' as well.

Is there a way to instruct typescript to iterate through the string and capture all desired literals?

Appreciate any assistance!

Answer №1

There isn't a direct iterative method for this task, but an alternative recursive approach can be used. Transforming it into a tail-recursive form may allow processing of long strings efficiently. Here's one potential solution:

type X<T extends string, A extends string = never> =
    T extends `${string}${'*('}${infer U}${')+'}${infer R}` ?
    X<R, A | U> : A;

The X<T> function is designed to parse strings using template literal types, with an added accumulator type parameter A to store collected matches. When a string matches the pattern, U represents the initial match and R holds the remaining portion. Recursing with

X<R, A | U></code appends the new match <code>U
to the existing accumulator A. Otherwise, if there are no matches found, the function returns A.

Testing examples:

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"

Results look accurate.

Access code on playground here

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Assign custom keys to request object parameters before reaching the controller in the map

I have a Loopback 4 application where the request object's property keys are in snake_case and they correspond to our database column names which are in StudlyCase. What I want is to change the application property names to camelCase. This means that ...

Implementing conditional asynchronous function call with identical arguments in a Typescript React project

Is there a way in React to make multiple asynchronous calls with the same parameters based on different conditions? Here's an example of what I'm trying to do: const getNewContent = (payload: any) => { (currentOption === myMediaEnum.T ...

Sending the :id parameter to the Service component

In the early days of my Angular journey, I have a simple question. Currently, I am utilizing the WordPress REST API to showcase a list of posts from a specific category by using posts?categories={ID HERE}. However, I am facing an issue in passing the ID f ...

Attempting to invoke a promise within a function yields an error message stating that it lacks call signatures

Recently, I came across this interesting class: export class ExponentialBackoffUtils { public static retry(promise: Promise<any>, maxRetries: number, onRetry?: Function) { function waitFor(milliseconds: number) { return new Pr ...

Embedded template does not utilize property binding ngif with any directive

I am currently working on an Angular (Angular2 RC4) application and I'm facing some challenges running it with the live server in nodejs. Any suggestions on how to troubleshoot the error showing up in the Chrome console would be greatly appreciated. ...

What is the best approach for retrieving an image efficiently with Angular HttpClient?

My backend currently sends back an image in response. When I access this backend through a browser, the image is displayed without any issues. The response type being received is 'image/jpeg'. Now, I am exploring different methods to fetch this ...

Error in Typescript: Function expects two different types as parameters, but one of the types does not have the specified property

There's a function in my code that accepts two types as parameters. handleDragging(e: CustomEvent<SelectionHandleDragEventType | GridHandleDragEventType>) { e.stopPropagation(); const newValue = this.computeValuesFromPosition(e.detail.x ...

Having trouble accessing store state in Angular with NGXS

In the parent component, I am dispatching an action and hoping to receive the dispatched array in the child component. To achieve this, I have implemented the following code: export class ListComponent implements OnInit { @Select(ProductState.getProductD ...

Definition of Angular 2 File

I have developed a custom Gantt chart library using D3 in vanilla JavaScript. Now, I am trying to integrate it into my Angular 2 application. After installing D3 via npm and adding the necessary type files and the Gantt chart module to node_modules, I enco ...

Transform the `PascalCase` format into `strictCamelCase` in TypeScript type conversion

By utilizing the built-in Uncapitalize<S> function, you can easily convert a string like FooBar to fooBar: const fooBar: Uncapitalize<'FooBar'> = 'fooBar'; However, this method proves inadequate when dealing with class name ...

Encountering unanticipated breakpoints in compiled .Next files while using Visual Studio Code

As a newcomer to NextJS, I have encountered an issue that is disrupting my workflow. I followed the instructions in https://nextjs.org/docs/advanced-features/debugging#using-the-debugger-in-visual-studio-code to set up my launch.json file. Although I am ...

`Angular Image Upload: A Comprehensive Guide`

I'm currently facing a challenge while attempting to upload an image using Angular to a Google storage bucket. Interestingly, everything works perfectly with Postman, but I've hit a roadblock with Angular Typescript. Does anyone have any suggesti ...

Progressive series of observable conditions

The issue at hand: I am faced with the task of checking multiple conditions, some of which lead to the same outcome. Here is the current flow: First, I check if a form is saved locally If it is saved locally, I display text 1 to the user If not saved l ...

Is it possible to loop through a subset of a collection using *ngFor?

Is it possible to iterate through a specific range of elements in a collection using *ngFor? For instance, I have a group of checkboxes with their form control name and label specified as follows: [{id: 'c1', label: 'C1'}, ...] Assum ...

Is there a way to turn off tsc pretty printing using the configuration file?

My typescript program is intentionally broken but I want to fix it. 12:17:23:~/hello $ cat hello.ts console.log("Hello World" 12:17:29:~/hello $ cat package.json { "dependencies": { "typescript": "^5.2.2" ...

Reasons Why Optional Chaining is Not Utilized in Transpiling a Node.js + TypeScript Application with Babel

Currently, I am delving into Babel in order to gain a deeper understanding of its functionality. To facilitate this process, I have developed a basic API using Node.js and TypeScript. Upon transpiling the code and initiating the server, everything operates ...

Utilizing Jest and nest.js for testing with absolute paths

Looking at my jest configuration inside the package.json: "jest": { "moduleFileExtensions": [ "js", "json", "ts" ], "moduleDirectories":["node_modules", "src" ...

The parameter 'EventTypes' cannot be assigned to a type of string

I am working on enhancing the functionality of the function provided below by adding types to it, clickEvent(event:Event) { this.event = event } The HTML Code: <a [href]="href" [target]="target" (click)="clickEvent('text')"></ ...

Displaying a React component within a StencilJS component and connecting the slot to props.children

Is there a way to embed an existing React component into a StencilJS component without the need for multiple wrapper elements and manual element manipulation? I have managed to make it work by using ReactDom.render inside the StencilJS componentDidRender ...

Securing redirection in WebPart using Azure AD: Best practices

I've successfully created a Sharepoint Webpart with a straightforward goal: authenticate users on an external website embedded within Sharepoint. This external site utilizes Azure AD for user logins. However, my current implementation has a significa ...