Hacktoberfest 2026: as issues que os mantenedores marcaram para outubro, abertas e boas para iniciantes. Ver issues do Hacktoberfest

[Router/FS] Trailing slash in routePathFromFile breaks TypeScript inference for nested paths in `paths` proxy

Fechada Para iniciantes
#652 0 comentários 0 reações 0 responsáveis Ver no GitHub

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 paths proxy: paths.posts(id).edit(), TypeScript selects the first matching overload signature (which terminated at PathEnd due to the empty segment) and throws:
    error TS2339: Property 'edit' does not exist on type 'PathEnd<DefaultSearchTypes, { id: string; }>'.
    
  • Meanwhile, at runtime, createPathsProxy works 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
  1. filesystem-routing should emit /posts/:id (without trailing slash) for posts/[id]/index.tsx.
  2. 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

Primeiros passos

  1. Leia a issue inteira e depois o guia de contribuição do projeto.
  2. Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
  3. Faça um fork do repositório e trabalhe em uma branch.
  4. Abra um pull request que referencie o número da issue.

Mais de solidjs/solid-router

Todas as issues de solidjs/solid-router

Issues semelhantes

Mais issues de TypeScript

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.