type IsArr<T> = T extends `${string}...${string}` ? true : false
type Extract<T> = T extends `[...${infer F}]` | `...${infer F}` ? F : T
type DynamicRoute<T extends string, _Res extends Record<string, string | string[]> = {}> = T extends `${infer A}[...]${infer B}`
? DynamicRoute<`${A}${B}`, _Res & { '...': string }>
: T extends `${string}]/[...${string}`
? never
: T extends `${infer A}[[${ infer F }]]${ infer B }`
? DynamicRoute<`${A}${B}`, _Res & ( Extract<F> extends '' ? {} : { [K in Extract<F>]?: IsArr<F> extends true ? string[] : string } ) >
: T extends `${infer A}[${ infer F }]${ infer B }`
? DynamicRoute<`${A}${B}`, _Res & ( Extract<F> extends '' ? {} : { [K in Extract<F>]: IsArr<F> extends true ? string[] : string } ) >
: { [K in keyof _Res]: _Res[K] }
Solution by lvjiaxuan #33614
type DynamicRoute<T extends string, L extends string = '', O = {}, Ambiguity extends string = ''>
= Ambiguity extends '⛔⛔' ? never
: ExtractNext<T, L> extends [infer L extends string, infer S extends NonEmpty]
? S extends `[${infer P extends NonEmpty}]`
? P extends `[...${infer G extends NonEmpty}]` ? DynamicRoute<T, L, O & {[K in G]?: string[]}, `${Ambiguity}â›”`>
: P extends `...${infer G extends NonEmpty}` ? DynamicRoute<T, L, O & {[K in G]: string[]}, `${Ambiguity}â›”`>
: DynamicRoute<T, L, O & {[K in P]: string}, Ambiguity>
: DynamicRoute<T, L, O, ''>
: {[K in keyof O]: O[K]}
type ExtractNext<T extends string, L extends string = ''>
= T extends `${L}/${infer S extends NonEmpty}/${any}` ? [`${L}/${S}/`, S]
: T extends `${L}${infer S extends NonEmpty}/${any}` ? [`${L}${S}/`, S]
: T extends `${L}/${infer S extends NonEmpty}` ? [`${L}/${S}`, S]
: T extends `${L}${infer S extends NonEmpty}` ? [`${L}${S}`, S]
: []
type NonEmpty = `${any}${any}`
Solution by teamchong #33350