feat(router-generator): add isolatedDeclarations config option#7289
feat(router-generator): add isolatedDeclarations config option#7289guru-irl wants to merge 3 commits intoTanStack:mainfrom
Conversation
When `isolatedDeclarations: true` is set in tsr.config.json, the generator
emits explicit `: any` type annotations on route constants:
const PostsRoute: any = PostsRouteImport.update({...} as any)
Without this annotation, TypeScript and oxc raise TS9010 ("Variable must have
an explicit type annotation with --isolatedDeclarations") because the return
type of `.update()` must be inferred across files.
The option defaults to `false` to preserve existing behaviour. It is a no-op
when `disableTypes: true` (JS output).
Adds an `isolated-declarations` test fixture (copied from `single-level`) with
a snapshot that asserts the `: any` annotations are emitted.
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughThis pull request introduces a new optional configuration flag, Changes
Poem
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Bundle Size Benchmarks
Trend sparkline is historical gzip bytes ending with this PR measurement; lower is better. |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/router-generator/tests/generator.test.ts (1)
124-126: Add one combo fixture to lock thedisableTypesno-op contract.Consider adding a dedicated folder/case for
isolatedDeclarations: true+disableTypes: trueso this behavior is snapshot-guarded going forward.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/router-generator/tests/generator.test.ts` around lines 124 - 126, Add a new combo fixture/case that sets both config.isolatedDeclarations = true and config.disableTypes = true so the no-op contract for disableTypes is snapshot-guarded; create a dedicated test folder/case name (e.g., "isolated-declarations-disable-types") in the generator fixtures and ensure the test runner picks it up and a snapshot is committed to lock current behavior for the combination, referencing the config object and the existing 'isolated-declarations' case handling to mirror how other combos are added.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@packages/router-generator/tests/generator.test.ts`:
- Around line 124-126: Add a new combo fixture/case that sets both
config.isolatedDeclarations = true and config.disableTypes = true so the no-op
contract for disableTypes is snapshot-guarded; create a dedicated test
folder/case name (e.g., "isolated-declarations-disable-types") in the generator
fixtures and ensure the test runner picks it up and a snapshot is committed to
lock current behavior for the combination, referencing the config object and the
existing 'isolated-declarations' case handling to mirror how other combos are
added.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: decbf11b-b36c-4834-a4cc-4c988a7cfab5
📒 Files selected for processing (7)
packages/router-generator/src/config.tspackages/router-generator/src/generator.tspackages/router-generator/tests/generator.test.tspackages/router-generator/tests/generator/isolated-declarations/routeTree.snapshot.tspackages/router-generator/tests/generator/isolated-declarations/routes/__root.tsxpackages/router-generator/tests/generator/isolated-declarations/routes/index.tsxpackages/router-generator/tests/generator/isolated-declarations/routes/posts.tsx
…tants and header Three correctness gaps in the original PR: 1. RouteWithChildren constants (generated by buildRouteTreeConfig for parent routes with children) were missing ': any' annotations. Add isolatedDeclarations param to buildRouteTreeConfig and propagate it through recursive calls. 2. rootRouteWithChildren (generated when the root route has component piece files) was also missing ': any'. Apply the same conditional. 3. The default routeTreeFileHeader includes '// @ts-nocheck', which opts the generated file out of type-checking entirely — defeating the purpose of isolatedDeclarations mode. Automatically strip '// @ts-nocheck' from the header when isolatedDeclarations: true. Add 'isolated-declarations-nested' fixture to cover the WithChildren code path (PostsRouteWithChildren: any on line 92 of snapshot). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
// @ts-nocheck is intentionally included in TanStack's default routeTreeFileHeader. Users who need isolatedDeclarations type-checking should configure a custom routeTreeFileHeader that omits it — that is the right locus of control, not the generator silently overriding it. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
not really. this either needs to be fixed correctly or we cant support this |
@schiller-manuel Yep yep, this is a vibe coded draft. I'll update this with real code EOD |
Summary
When a project enables TypeScript's
--isolatedDeclarations(or the equivalent oxc setting), the route tree generated byrouter-generatorcurrently triggers TS9010:This happens because the type of
PostsRoutemust be inferred from the return type of.update()— which crosses a file boundary, violating the isolated-declarations constraint.Solution
Add an
isolatedDeclarationsboolean option totsr.config.json(defaults tofalse). When enabled, the generator emits explicit: anyannotations on route constants:The option is opt-in to avoid any impact on existing users. It is a no-op when
disableTypes: true.Type safety tradeoff
Using
: anyon route constants meanstypeof PostsRoute === any, which does collapse the router's type tree (breakinguseRouteContext,useParamsinference etc.). This is an accepted tradeoff for projects that needisolatedDeclarationscompliance — they already pay the same price for otheras anypatterns in the generated file.A future improvement could use a more precise type (e.g. the specific
Routeclass type), but that would require the generator to know the exact return type of.update(), which is not currently feasible.Test plan
isolated-declarationsgenerator test fixture (copied fromsingle-level): anyis emitted on route constants when option is enabledfalse)const X = import.update({} as any)+export interface I { '/': typeof X }→ TS9010 without: any, clean with: anySummary by CodeRabbit
Release Notes
New Features
isolatedDeclarationsconfiguration option to the router generator for enhanced type handling in route declarations.Tests
isolatedDeclarationsconfiguration.