Hacktoberfest 2026 : les issues que les mainteneurs ont marquées pour octobre, ouvertes et accessibles aux débutants. Parcourir les issues Hacktoberfest

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

Fermée Adaptée aux débutants
#652 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 1 jour

Personne n'a encore pris cette issue.

Évaluation

Difficulté
2/5
Temps estimé
1-3 heures
Accessibilité débutants
85/100
Type d'issue
Bug
Clarté
Clairement spécifiée
Activité
Active
Stack technique
typescript
Domaine
web-dev

Piste de recherche

Commencez dans filesystem-routing/dist/convention.js, au niveau de routePathFromFile, et reproduisez le chemin généré à partir de la structure de route posts/[id]/index.tsx. Vérifiez la déclaration générée et l’inférence TypeScript de paths.posts(id).edit(). C’est terminé lorsque les routes index génèrent /posts/:id sans barre oblique finale et que l’appel aux paths imbriqués se compile correctement.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

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(/\/+$/, "")}` : "/";
Langage dominant
TypeScript
Étoiles
1.3k
Forks
183
Merge moyen
14 h 35 min
PR mergées (30 j)
52

Préparer son environnement

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de solidjs/solid-router

Toutes les issues de solidjs/solid-router

Issues similaires

Plus d'issues TypeScript

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.