Estou tentando construir um tipo recursivo em TypeScript que resolva cada caminho de rota possível, incluindo caminhos aninhados, a partir de uma determinada configuração de rota. No entanto, estou encontrando problemas com restrições de tipo e inferência.
Eu defini as rotas usando uma interface TypedRoute e uma função createRoute:
interface TypedRoute<
Path extends string,
QueryParams extends Record<string, string> = {}
> {
path: Path;
queryParams?: QueryParams;
children?: TypedRoute<any, any>[];
}
function createRoute<
Path extends string,
QueryParams extends Record<string, string> = {}
>(config: TypedRoute<Path, QueryParams>) {
return config;
}
const routes = [
createRoute({
path: 'results/:id/foo/:bar'
}),
createRoute({
path: 'home',
children: [
createRoute({
path: 'bar',
children: [
createRoute({ path: 'baz' })
]
}),
],
}),
]
Agora, estou tentando criar um tipo ExtractRoutePaths que extraia recursivamente todos os caminhos possíveis:
type ExtractRoutePaths<T extends readonly TypedRoute<any, any>[]> =
T extends readonly []
? never
: T extends readonly [infer First, ...infer Rest]
? First extends TypedRoute<infer P, any>
? First extends { children: infer C }
? C extends readonly TypedRoute<any, any>[]
? `{P}` | ExtractRoutePaths<C, `${P}/`> | ExtractRoutePaths<Rest extends readonly TypedRoute<any, any>[] ? Rest : never>
: `${P}` | ExtractRoutePaths<Rest extends readonly TypedRoute<any, any>[] ? Rest : never>
: `${P}` | ExtractRoutePaths<Rest extends readonly TypedRoute<any, any>[] ? Rest : never>
: ExtractRoutePaths<Rest extends readonly TypedRoute<any, any>[] ? Rest : never>
: never;
Espero que as rotas sejam:
resultados/:id/foo/:bar | casa | início/bar | casa/bar/baz
O que estou fazendo de errado e como posso construir corretamente esse tipo recursivo para extrair todos os caminhos possíveis, incluindo os aninhados?