Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

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

Aperta Adatta ai principianti
#652 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
85/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
typescript
Ambito
web-dev

Direzione di ricerca

Inizia in filesystem-routing/dist/convention.js, all'interno di routePathFromFile, e riproduci il percorso generato dalla struttura della route posts/[id]/index.tsx. Controlla la dichiarazione generata e l'inferenza TypeScript di paths.posts(id).edit(). Il lavoro è completato quando le route index emettono /posts/:id senza una barra finale e la chiamata ai paths annidati viene compilata correttamente.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

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(/\/+$/, "")}` : "/";
Lingua principale
TypeScript
Stelle
1.3k
Fork
182
Merge medio
22h 57m
PR unite (30g)
37

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di solidjs/solid-router

Tutte le issue di solidjs/solid-router

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.