vercel / vercel/next.js

typedRoutes invalid Link href is not enforced by tsc in a workspace app unless .next/types/link.d.ts is manually referenced

Open
#93,007 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

TypeScript
Dominant language
JavaScript
Stars
142k
Forks
32.4k
Avg merge
2d 14h
Merged PRs (30d)
351

Description

Link to the code that reproduces this issue

https://github.com/jakeleventhal/next-typed-routes-workspace-tsc-repro

To Reproduce
  1. Clone the repo
  2. Install dependencies:
bun install
  1. Generate route types:
bun run -F @repro/web typegen
  1. Confirm the generated files:
  • apps/web/.next/types/routes.d.ts contains only /
  • apps/web/.next/types/link.d.ts contains the next/link and next/navigation route augmentations
  • apps/web/next-env.d.ts imports ./.next/types/routes.d.ts
  1. Run TypeScript from the app package:
bun run -F @repro/web tsc
bun run -F @repro/web tsc:noemit
  1. Notice that both commands succeed, even though apps/web/src/app/page.tsx contains an invalid route:
<Link href="/definitely-not-a-real-route">Broken typed route</Link>
  1. Now run the comparison script that explicitly loads the generated link.d.ts file:
bun run -F @repro/web tsc:with-link-augmentation
  1. Notice that this fails immediately with:
src/app/page.tsx(6,10): error TS2322: Type '"/definitely-not-a-real-route"' is not assignable to type 'UrlObject | RouteImpl<"/definitely-not-a-real-route">'.
Current vs. Expected behavior

Current:

  • typedRoutes: true is enabled
  • next typegen generates both routes.d.ts and link.d.ts
  • In this workspace-style setup, both tsc --build and tsc --noEmit still accept an invalid Link href
  • If I manually reference .next/types/link.d.ts, the same invalid route is rejected

Expected:

After next typegen, plain TypeScript checking should reject the invalid Link href without requiring a manual reference to .next/types/link.d.ts.

This expectation seems consistent with the docs for next typegen, which say:

next typegen && tsc --noEmit

should validate route usage externally.

Provide environment information
Operating System:
  Platform: darwin
  Arch: arm64
Binaries:
  Node: 24.12.0
  Bun: 1.3.12
Relevant Packages:
  next: 16.2.4
  react: 19.2.0
  react-dom: 19.2.0
  typescript: 5.9.3
Which area(s) are affected? (Select all that apply)

TypeScript

Which stage(s) are affected? (Select all that apply)

next typegen, tsc --build, tsc --noEmit

Additional context

The repro is intentionally a tiny monorepo/workspace because I could not reproduce this in a standalone single-package Next app. The mismatch seems to depend on a shared tsconfig package + app package setup.

The generated next-env.d.ts in the repro currently looks like this:

/// <reference types="next" />
/// <reference types="next/image-types/global" />
import "./.next/types/routes.d.ts";

That appears to be enough for route metadata, but not enough for next/link route enforcement in this setup.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the linked workspace reproduction and run bun install, bun run -F @repro/web typegen, and the three TypeScript commands. Compare apps/web/next-env.d.ts, .next/types/routes.d.ts, .next/types/link.d.ts, and apps/web/src/app/page.tsx to trace which generated declarations are loaded. Done means plain tsc commands reject the invalid Link href without a manual link.d.ts reference.

Written by the indexing model from the issue text.

Assessment

Tech stack
bun, next.js, react, typescript
Domain
developer-experience, tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.