feat(types): opt-in flat NitroFetchRequest to bound $fetch type instantiation - #4477
feat(types): opt-in flat NitroFetchRequest to bound $fetch type instantiation#4477Killian-Aidalinfo wants to merge 1 commit into
Conversation
…ntiation
Projects with a large generated InternalApi (hundreds of routes) can hit
"Type instantiation is excessively deep and possibly infinite" (TS2589) and
"Excessive stack depth comparing types" (TS2321) on typed $fetch / useFetch /
useAsyncData / event.$fetch, because the NitroFetchRequest route-key union is
used as the generic constraint and re-scored at every call site.
Add an opt-in NitroFetchConfig interface: when a project sets
`{ flatRequest: true }`, NitroFetchRequest resolves to `string`, which stops the
per-call-site scoring of the route union. Response typing is preserved
(MatchedRoutes still resolves the return from the URL literal); only request-key
autocomplete is traded away. Default behavior is unchanged (union), so existing
users are unaffected.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
@Killian-Aidalinfo is attempting to deploy a commit to the Nitro Team on Vercel. A member of the Team first needs to authorize it. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthrough
ChangesFetch request typing
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related issues
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ 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 |
|
Hi @pi0 , I opened this PR to fix the type-instantiation issues we're seeing with the Go version of vue-tsc (tsgo). There have already been several issues opened on the Microsoft side, but they were closed as intended / not planned, with the recommendation that libraries patch their own types instead. The approach here is intentionally minimal and opt-in. It adds an escape hatch for users hitting these limits while keeping the current behavior by default. Response typing is still preserved, the only trade-off is request-path autocomplete when the option is enabled. I tested it on a fairly large Nuxt 4 project (~846 routes), and it gets rid of the TS2589/TS2321 errors on both tsc and tsgo without introducing any new ones. Let me know what you think 🙂 |
🔗 Linked issue
Closes #4476
❓ Type of change
📚 Description
Apps with a large generated
InternalApi(hundreds of routes) hit TS2589 (Type instantiation is excessively deep) and, undertsgo, a flood of TS2321 on typed$fetch/useFetch/useAsyncData/event.$fetchcalls.NitroFetchRequestis the union of all route keys used as the generic constraint (R extends NitroFetchRequest), so every call site re-scores the URL literal against the full union viaMatchedRoutes/AvailableRouterMethod/TypedInternalResponse.tscsits just under its 5M instantiation limit;tsgo(stricter, stable type ordering) tips over → the whole diagnostic class.This is the same family the TypeScript team closes as intended /
NOT_PLANNED, pointing to libraries to fix their types (microsoft/typescript-go#929, #4465, #787) — so the mitigation belongs here.This PR adds an opt-in, non-breaking escape hatch — a
NitroFetchConfiginterface:When opted in,
NitroFetchRequestresolves tostring, which stops the per-call-site union scoring. Default is unchanged (the union) so existing users keep full request autocomplete + typing. When enabled, response typing is preserved (MatchedRoutes<R>still resolves the return type from the URL literal); only request-key autocomplete is traded away.✅ Why this approach
TypedInternalResponse/MatchedRoutesare untouched.src/types/fetch/fetch.ts.Alternatives rejected: making
MatchedRoutesnon-recursive or emptyingInternalApidestroys response typing (trades TS2589 for a flood of TS2339/TS18046); changing only the$FetchdefaultRhas no effect (the union must stay in the constraint for autocomplete, and that union is exactly what over-instantiates).🧪 Measured
On a real Nuxt 4 app (~846 routes): removes the entire TS2589/TS2321 class on both
tscandtsgowith zero new errors, response types preserved.