type SplitPath

= P extends `${infer X}/${infer Y}` ? [X, ...SplitPath] : [P] type KeepPathVar

= P extends `:${infer Var}` ? [Var] : [] type Cast = A extends B ? A : B type FilterPathVar

= P extends [`${infer Head}`] ? KeepPathVar : P extends [infer Head, ...infer Tail] ? [...KeepPathVar>, ...FilterPathVar>] : [] type ToUnion

= P[number] export type PathVariables

= Record>>, string> export const getPathVariables =

(p: P): FilterPathVar> => { const parts = p.split('/') const vars = parts.filter((p) => p.startsWith(':')) return vars.map((v) => v.substring(1)) as FilterPathVar> } export const mapPathFromExpressToOpenAPI = (p: string): string => { const parts = p.split('/') const vars = parts.map((p) => (p.startsWith(':') ? `{${p.substring(1)}}` : p)) return vars.join('/') }