Skip to content

Accept undefined on optional RouteDefinition properties - #599

Merged
ryansolid merged 1 commit into
nextfrom
fix-598-exact-optional
Sep 8, 2026
Merged

Accept undefined on optional RouteDefinition properties#599
ryansolid merged 1 commit into
nextfrom
fix-598-exact-optional

Conversation

@ryansolid

Copy link
Copy Markdown
Member

Closes #598

With exactOptionalPropertyTypes: true, createRouter({ routes: fileRoutes(pageRoutes) }) fails against filesystem-routing's generated virtual:file-routes types.

Root cause is in the router, not the generator: FileRouteFrom<E> (in @solidjs/router/fs) deliberately maps a leaf entry to a required children: undefined / component: undefined key — mirroring what fileRoutes() emits at runtime — and RouteDefinition's optional properties were prop?: T without | undefined, which the flag rejects. The generator's children?: undefined for absent children is fine on its own and already matched FileRouteEntry's input types.

Changes

  • RouteDefinition: every optional property (path, matchFilters, preload, children, component, search, info) now admits | undefined.
  • Same treatment for the sibling shapes a route tree flows through: DefinedRoute and the defineRoute overload inputs, FileRouteConfig and the defineFileRoute config, FileRouteEagerRef.src.
  • Runtime: createBranches used hasOwnProperty("path") to default a pathless route to ""; an explicit path: undefined would have slipped through. It now checks def.path === undefined. Everything else already treated absent and undefined alike.
  • Test: test/exact-optional-types.spec.ts compiles test/fixtures/exact-optional-routes.ts through the compiler API with exactOptionalPropertyTypes: true (reporting only the fixture's diagnostics — the source itself does not opt into the flag, 19 unrelated errors). The fixture mirrors the plugin's generated pageRoutes declaration and pushes it through fileRoutes(), createRouter() (typed paths intact), defineRoute, and defineFileRoute. 7 errors before, 0 after.
  • Changeset (patch).

Verified against a fresh /tmp project (solid-js@2.0.0-rc.7, @solidjs/router@2.0.0-next.22, filesystem-routing@0.3.0, @solidjs/vite-plugin@3.0.0-next.38) with the flag on: tsc reproduces the issue's error against the published package and passes against the pnpm pack tarball of this branch. pnpm build, test:types, jsdom + server vitest suites, and attw --pack . --profile esm-only are all green.

Made with Cursor

Under exactOptionalPropertyTypes, an optional property only admits an
explicit undefined when its type says so. fileRoutes() maps manifest
leaves to { component, children: undefined } (a required key, mirroring
the runtime), which RouteDefinition's plain optional props rejected. Add
| undefined to every optional property of RouteDefinition, DefinedRoute,
FileRouteConfig and the defineRoute/defineFileRoute inputs, and make the
one presence check in createBranches (hasOwnProperty('path')) treat an
explicit path: undefined as pathless like an absent key.

Adds a compile-time regression test that type-checks a fixture shaped
like filesystem-routing's generated pageRoutes declaration with the flag
on, reporting only the fixture's diagnostics.
@changeset-bot

changeset-bot Bot commented Sep 8, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 12a2500

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@solidjs/router Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@ryansolid
ryansolid merged commit 44eb23c into next Sep 8, 2026
3 checks passed
@ryansolid
ryansolid deleted the fix-598-exact-optional branch September 8, 2026 17:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant