Härled uttryck från en sträng i Typescript


Givet koden nedan verkar allt vara okej (se lekplatsen):

type PathParam<T> = T extends `${string}:${infer U}` ? U : never;

type Param = PathParam<"/post/:post_id">;
// type Param = "post_id"

Men det blir lite komplicerat när det finns ytterligare text efter sökvägsparametern.

type PathParam<T> = T extends `${string}:${infer U}` ? U : never;

type Param = PathParam<"/post/:post_id/likes/:like_id">;
// type Param = "post_id/likes/:like_id"

Jag kan förstå varför det misslyckas, men jag är inte säker på hur man kan härleda endast mönstret :$ {string} i TypeScript. I regex skulle det vara ekvivalent med /:[a-z_]+/g

Så min fråga är - hur kan jag få Param att härledas som följande typ?

type Param = "post_id" | "like_id"

Svar #1

Du behöver en rekursiv typ för att utföra en viss loop för att konstruera en union med dynamisk storlek.

försök :

type PathParam<T extends string, Res extends string = never> = 
    T extends `${string}:${infer U}/${infer Rest}` 
    ?  U | PathParam<Rest, Res> :
    T extends `${string}:${infer L}` 
    ?  L : Res;