[Router/FS] Trailing slash in routePathFromFile breaks TypeScript inference for nested paths in `paths` proxy
Mantenedores costumam responder em até 1 dia
Ninguém assumiu esta issue ainda.
Avaliação
- Dificuldade
- 2/5
- Tempo estimado
- 1-3 horas
- Facilidade para iniciantes
- 85/100
- Tipo de issue
- Bug
- Clareza
- Claramente especificada
- Status de atividade
- Ativa
- Stack de tecnologia
- typescript
- Domínio
- web-dev
Direção de pesquisa
Comece em filesystem-routing/dist/convention.js, em routePathFromFile, e reproduza o caminho gerado a partir da estrutura de rota posts/[id]/index.tsx. Verifique a declaração gerada e a inferência de TypeScript de paths.posts(id).edit(). Está concluído quando as rotas index emitirem /posts/:id sem uma barra no final e a chamada aos paths aninhados compilar com sucesso.
Escrita pelo modelo de indexação a partir do texto da issue.
Descrição
Describe the bug
When using file-system routing with index.tsx inside dynamic route folders, filesystem-routing produces paths with an unintended trailing slash (e.g. /posts/:id/ instead of /posts/:id).
This trailing slash causes @solidjs/router's type generator (SegmentsOf) to split the path into ["posts", ":id", ""] with a phantom empty segment "" at the end. As a result:
- When calling a nested subpath on the
pathsproxy:paths.posts(id).edit(), TypeScript selects the first matching overload signature (which terminated atPathEnddue to the empty segment) and throws:error TS2339: Property 'edit' does not exist on type 'PathEnd<DefaultSearchTypes, { id: string; }>'. - Meanwhile, at runtime,
createPathsProxyworks completely fine and outputs"/posts/1/edit".
Your Example Website or App
Blank
Steps to Reproduce the Bug or Issue
Step 1: In a project using @solidjs/router/fs and filesystem-routing, create the following route structure:
src/routes/
└── posts/
├── [id]/
│ ├── index.tsx # Post detail
│ └── edit.tsx # Post edit
└── index.tsx # Posts list
Step 2: Generate the route types using fileRoutes({ types: true }).
Notice in the generated declaration, the route path is emitted with a trailing slash:
path: "/posts/:id/"
Step 3: Attempt to use the typed paths proxy in any component:
import { paths } from "~/router";
// ❌ TypeScript Error: Property 'edit' does not exist on type 'PathEnd<...>'
paths.posts(1).edit();
Minimal TypeScript reproduction (no file system needed):
import { createRouter, defineRoutes } from "@solidjs/router";
const Router = createRouter({
routes: defineRoutes([
{ path: "/posts/:id/" }, // generated from [id]/index.tsx
{ path: "/posts/:id/edit" } // generated from [id]/edit.tsx
])
});
// ❌ TypeScript Error: Property 'edit' does not exist on type 'PathEnd<...>'
Router.paths.posts(1).edit();
// ✅ If the trailing slash is removed, it compiles cleanly:
const FixedRouter = createRouter({
routes: defineRoutes([
{ path: "/posts/:id" },
{ path: "/posts/:id/edit" }
])
});
FixedRouter.paths.posts(1).edit(); // OK!
Expected behavior
filesystem-routingshould emit/posts/:id(without trailing slash) forposts/[id]/index.tsx.paths.posts(id).edit()should be accepted by TypeScript and infer the full path"/posts/1/edit"without type errors.
Screenshots or Videos
No response
Platform
- OS: Windows 10
- Node: 24
- SolidJS:
2.0.0-rc.6 @solidjs/router:2.0.0-next.34(latest)filesystem-routing:0.4.0(latest)- TypeScript:
5.9.2
Additional context
The bug originates in filesystem-routing/dist/convention.js:
export function routePathFromFile(routeFile) {
const routePath = routeFile
.slice(1)
.replace(/(^|\/)index$/, "$1") // ⚠️ BUG: Replaces "/index" with "$1" ("/") instead of stripping the slash
.replace(/\[([^/]+)\]/g, ...);
return routePath?.length > 0 ? `/${routePath}` : "/";
}
Replacing /(^|\/)index$/ with $1 preserves the preceding slash, turning posts/[id]/index into posts/[id]/.
Proposed fix:
- .replace(/(^|\/)index$/, "$1")
+ .replace(/\/index$/, "")
Or normalize trailing slashes on all non-root routes:
return routePath?.length > 0 ? `/${routePath.replace(/\/+$/, "")}` : "/";
- Linguagem predominante
- TypeScript
- Estrelas
- 1.3k
- Forks
- 183
- Merge médio
- 17h 18min
- PRs com merge (30d)
- 49
Preparar o ambiente
- Sem Dockerfile nem arquivo Docker Compose
- Sem modelo de pull request
- Ler o guia de contribuição
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Mais de solidjs/solid-router
-
Dificuldade 4/5 3-5 dias Facilidade para iniciantes 48/100
solidjs/solid-router#691 ·
Mantenedores costumam responder em até 1 dia
-
Forward pressed while a Back navigation is still loading is dropped; the URL and the rendered route get out of syncTalvez já em andamento @sean0407 assumiu há 1 dia. Aberta
Dificuldade 4/5 1-2 dias Facilidade para iniciantes 54/100
solidjs/solid-router#687 ·
Mantenedores costumam responder em até 1 dia
-
<A> costs ~6us of server CPU per instance during SSR (20x a plain <a>), mostly mergeProps/splitPropsTalvez já em andamento @birkskyum assumiu há 72 dias. Aberta1.x
Dificuldade 4/5 3-5 dias Facilidade para iniciantes 55/100
solidjs/solid-router#583 ·
Mantenedores costumam responder em até 1 dia
-
1.x enhancement
Dificuldade 3/5 1-2 dias Facilidade para iniciantes 38/100
solidjs/solid-router#518 · 2 comentários ·
Mantenedores costumam responder em até 1 dia
-
Dificuldade 4/5 3-5 dias Facilidade para iniciantes 35/100
solidjs/solid-router#482 · 2 comentários ·
Mantenedores costumam responder em até 1 dia
Todas as issues de solidjs/solid-router
Issues semelhantes
-
bug
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 78/100
endora-commerce/endora-commerce#397 ·
Mantenedores costumam responder em até 1 dia
-
level/task
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 68/100
wazuh/wazuh-dashboard-plugins#9472 ·
Mantenedores costumam responder em até 1 dia
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 63/100
Mantenedores costumam responder em até 1 dia
-
ready-for-agent
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 68/100
xavxyz/bei-shan-lin-shui#57 ·
Mantenedores costumam responder em até 1 dia
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 78/100
opennextjs/opennextjs-cloudflare#1461 ·
Mantenedores costumam responder em até 1 dia