Skip to content

feat(types): add ExtractRouteParams and route param inference#1327

Closed
productdevbook wants to merge 2 commits intomainfrom
feat/extract-route-params
Closed

feat(types): add ExtractRouteParams and route param inference#1327
productdevbook wants to merge 2 commits intomainfrom
feat/extract-route-params

Conversation

@productdevbook
Copy link
Copy Markdown
Member

@productdevbook productdevbook commented Mar 14, 2026

Summary

Closes #1053

Adds compile-time route parameter inference from path strings — zero runtime cost, purely type-level.

Before

app.get("/users/:id", (event) => {
  const params = getRouterParams(event);
  // params: Record<string, string> — no inference
});

After

app.get("/users/:id", (event) => {
  const params = getRouterParams(event);
  // params: { id: string } — inferred from path!
});

app.post("/users/:userId/posts/:postId", (event) => {
  const params = getRouterParams(event);
  // params: { userId: string; postId: string }
});

ExtractRouteParams utility type

Also exported as a standalone utility:

import type { ExtractRouteParams } from "h3";

type Params = ExtractRouteParams<"/users/:id/posts/:slug">;
// { id: string; slug: string }

Changes

  • src/types/_utils.ts: Add ExtractRouteParams<T> utility type with _Prettify for clean intersection flattening
  • src/types/h3.ts: Add generic overloads to all HTTP method declarations (get, post, etc.) that infer path params and pass narrowed event to handler
  • src/utils/request.ts: Update getRouterParams to use InferEventInput (matching readBody/getQuery pattern) so params flow from event generic
  • src/index.ts: Export ExtractRouteParams type

Design decisions

  • No runtime changes — all inference is erased at compile time
  • Backward compatible — generic overload is tried first, falls back to existing HTTPHandler overload
  • Static routes return Record<string, string> (not {}) to handle catchall/wildcard params
  • string extends T guard — when path is a plain string (not a literal), falls back to Record<string, string>

Test plan

  • 6 new type-level tests (ExtractRouteParams + route param inference)
  • All existing type tests pass (10/10)
  • Full test suite passes (954 tests, 43 files, 0 errors)
  • Zero type errors, zero source errors
  • Bundle size unaffected (types are erased)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Automatic route parameter type extraction now enables type-safe handler implementations. Route paths with dynamic parameters (e.g., /users/:id/posts/:slug) automatically infer typed parameters (e.g., { id: string; slug: string }), improving developer experience and reducing runtime errors.
    • Enhanced type inference across all HTTP method handlers with improved generic typing support, providing better IDE autocomplete and type checking.

Add ExtractRouteParams<Path> utility type that extracts parameter names
from route path strings at compile time:

  type P = ExtractRouteParams<"/users/:id/posts/:slug">
  // { id: string; slug: string }

Route methods (get, post, put, etc.) now infer route params from the
path string literal and pass them to the handler's event type. Combined
with the updated getRouterParams (now uses InferEventInput), this gives
automatic type inference:

  app.get("/users/:id", (event) => {
    const params = getRouterParams(event);
    // params is { id: string } — inferred from path
  });

Zero runtime changes — purely type-level improvement.

Closes #1053

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@productdevbook productdevbook requested a review from pi0 as a code owner March 14, 2026 21:06
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 14, 2026

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Walkthrough

This PR implements route parameter type inference for the H3 framework. It introduces utility types to extract route parameters from route strings (e.g., /users/:id/posts/:slug{ id: string; slug: string }), adds generic overloads to all HTTP methods in the H3 class for type-safe parameter access, and updates the getRouterParams utility function with generic type inference capabilities.

Changes

Cohort / File(s) Summary
Route Parameter Utilities
src/index.ts, src/types/_utils.ts
Introduced ExtractRouteParams<T> utility type with internal helpers _ExtractParams and _Prettify to recursively parse and extract route parameter names from route strings, exported publicly from package root.
H3 Class HTTP Method Overloads
src/types/h3.ts
Added generic overloads to ten HTTP methods (all, get, post, put, delete, patch, head, options, connect, trace) to enable type-safe router parameter inference via ExtractRouteParams<P> in handler event context.
Request Parameter Utilities
src/utils/request.ts
Generalized getRouterParams signature to accept type parameters and infer return type via InferEventInput, enabling flexible type inference for router parameters.
Type Tests
test/unit/types.test-d.ts
Added type-level tests validating ExtractRouteParams behavior, H3 method signatures, and getRouterParams type inference across various route patterns.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~35 minutes

Poem

🐰 Hops through routes with glee,
Parameters typed, wild and free,
No more shadows, strings unknown,
Type-safe paths, clearly shown!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding ExtractRouteParams type and enabling route parameter inference for type-safe route handlers.
Linked Issues check ✅ Passed The PR fully addresses issue #1053 by implementing type-level route parameter inference (ExtractRouteParams utility type), adding generic overloads to HTTP methods, and updating getRouterParams to support InferEventInput for param typing.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing route parameter inference: utility type definitions, HTTP method overloads, getRouterParams signature update, public exports, and type tests. No unrelated changes detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/extract-route-params
📝 Coding Plan
  • Generate coding plan for human review comments

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Mar 14, 2026

Open in StackBlitz

npm i https://pkg.pr.new/h3@1327

commit: 3a726c6

@productdevbook
Copy link
Copy Markdown
Member Author

Closing — PR #1217 by @luxass already covers this with a more comprehensive approach:

  • Uses rou3's InferRouteParams (PR feat(types): add InferRouteParams for param extraction rou3#168) instead of defining a separate type
  • Handles wildcards (*, **, **:name) which this PR doesn't
  • Also types event.context.params directly, not just getRouterParams()
  • Uses H3HandlerInterface<this> pattern which is cleaner for the method overloads

Apologies for the duplicate work — should have checked open PRs more carefully.

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.

infer route params

1 participant