fix(types): relax RouteMapGeneric constraint for interface-based RouteNamedMap#2624
Conversation
✅ Deploy Preview for vue-router canceled.
|
📝 WalkthroughWalkthroughThis pull request refines TypeScript generic constraints for route location type helpers. The RouteMap constraint is updated from Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Poem
🚥 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)
No actionable comments were generated in the recent review. 🎉 Tip Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord. 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 |
commit: |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #2624 +/- ##
=======================================
Coverage 85.58% 85.58%
=======================================
Files 86 86
Lines 9963 9963
Branches 2284 2285 +1
=======================================
Hits 8527 8527
Misses 1423 1423
Partials 13 13 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
posva
left a comment
There was a problem hiding this comment.
Thanks a lot! I didn't know we could self reference the type with keyof!
Problem
When using file-based routing (
vue-router/vite), the generatedtyped-router.d.tsaugmentsRouteNamedMapas an interface with literal route keys. However, 14 typed route helper types inroute-location.tsuse the constraintRouteMap extends RouteMapGenericwhereRouteMapGeneric = Record<string | symbol, RouteRecordInfoGeneric>.TypeScript interfaces with only literal keys do not have implicit index signatures (see TypeScript#15300), so the augmented
RouteNamedMapfails to satisfyRecord<string | symbol, ...>. This produces 12 TS2344 errors withskipLibCheck: falseand causes type inference blowups at scale (~30-40+ routes) even withskipLibCheck: true.Fixes posva/unplugin-vue-router#756
Solution
Replace the constraint
RouteMap extends RouteMapGenericwith the self-referentialRouteMap extends { [K in keyof RouteMap]: RouteRecordInfoGeneric }on all 14 typed route types inroute-location.ts.This preserves the semantic intent ("every value must be a RouteRecordInfoGeneric") without requiring string/symbol index signatures. The default
= RouteMapGenericremains valid.No runtime changes, types only.
6 alternative solutions were analyzed -- this is the only one that fixes the constraint error while preserving type safety (invalid route names like
/nonexistentare still correctly rejected).Changes
packages/router/src/typed-routes/route-location.ts-- 14 constraint sites + 1 importpackages/router/__tests__/routeLocation.test-d.ts-- type test usinginterface(nottype) for RouteMapTests
interface(nottype) for RouteMap to cover the exact scenario that breaks in real projects. Existing tests only usetypealiases, which get implicit index signatures and sidestep the issue.pnpm -C packages/router build-- SUCCESSpnpm -C packages/router test:types-- no new errorspnpm -C packages/router test:unit-- 1483 passed, no regressions, no type errorsAlso happy to adjust if maintainers prefer another approach.
Summary by CodeRabbit
Tests
Refactor