Skip to content

fix(types): accept Express/Koa request types in Request constructor#446

Open
dhensby wants to merge 1 commit into
node-oauth:masterfrom
dhensby:fix/types-request-framework-compat
Open

fix(types): accept Express/Koa request types in Request constructor#446
dhensby wants to merge 1 commit into
node-oauth:masterfrom
dhensby:fix/types-request-framework-compat

Conversation

@dhensby

@dhensby dhensby commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

What

Loosens the Request constructor's headers/query typing from Record<string, string> to Record<string, any>, fixing the compile-time regression introduced in 5.2.1 (#362) for framework request objects.

This addresses the Express/Koa typing-compatibility part of #356 — it does not close it (see Scope).

Why

Since 5.2.1, passing real framework request data fails to type-check:

  • Express 5: req.query is ParsedQs ({ [k]: string | ParsedQs | (string | ParsedQs)[] | undefined }) — not assignable to Record<string, string>.
  • Koa: headers are IncomingHttpHeaders (string | string[] | undefined).

string | string[] isn't broad enough (ParsedQs has nested / undefined values), so Record<string, any> is the value type that accepts them.

Backwards compatibility

  • Widening only — existing Record<string, string> callers still compile (stringany), and reads stay any-compatible (no forced narrowing), so no consumer breaks.
  • headers/method/query remain required (matching the runtime, which throws if they're missing), so a raw Fetch Request (no query) still correctly fails to compile rather than compiling and throwing at runtime.

Verified with tsc: Express 5 ParsedQs / Koa IncomingHttpHeaders / plain string maps all compile; a query-less object is still rejected.

Scope

This is the typing half of #356. First-class Fetch Request support (the issue's original title) is a separate feature: a Fetch Request has no query and an async-stream body, so it can't be handled in the synchronous constructor — it needs an adapter or a dedicated async entry point. That remains open on #356 to design.

🤖 Generated with Claude Code

Since 5.2.1 the Request constructor typed `headers` and `query` as
`Record<string, string>`, which rejects common framework request shapes at
compile time — e.g. Express 5's `req.query` (`ParsedQs`, whose values can be
nested or `undefined`) and Koa's `IncomingHttpHeaders`
(`string | string[] | undefined`). Widen both to `Record<string, any>`, which
accepts those shapes while remaining backwards compatible with plain
`Record<string, string>` callers. `headers`/`method`/`query` stay required, so
a raw Fetch `Request` (which has no `query`) still correctly fails to
type-check.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@dhensby dhensby force-pushed the fix/types-request-framework-compat branch from 436eec4 to b87c558 Compare June 16, 2026 14:24
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.

1 participant