Skip to content

fix(rest): Guard RestEndpoint against O=any in subclassed constructors#3847

Open
ntucker wants to merge 1 commit intomasterfrom
fix/pathargs-any-subclass-constructor
Open

fix(rest): Guard RestEndpoint against O=any in subclassed constructors#3847
ntucker wants to merge 1 commit intomasterfrom
fix/pathargs-any-subclass-constructor

Conversation

@ntucker
Copy link
Copy Markdown
Collaborator

@ntucker ntucker commented Apr 1, 2026

Follows up on #3845.

Motivation

#3845 fixed PathArgs<any> returning a restrictive index-signature type, but the any also propagates through the searchParams conditional in RestEndpoint<O> and RestEndpointConstructorOptions<O>. When subclassing with O extends RestGenerics = any, the [O['searchParams']] extends [undefined] non-distributive wrapper (added in #3782 for TS6) prevents any from passing through, producing the same restrictive type at a higher level.

Solution

Add unknown extends O ? any : guard before the searchParams conditional in both RestEndpoint<O> and RestEndpointConstructorOptions<O>. This catches O = any before it reaches PathArgs, so subclassed endpoints accept concrete body types.

Includes a detailed comment explaining a known limitation: TypeScript may partially infer O from constructor arguments, widening path literals (e.g., '/users/:id') to string (the RestGenerics constraint) instead of preserving the literal. This is inherent to TypeScript's class constructor inference with complex conditional parameter types and would require restructuring the constructor options type to fix.

Open questions

N/A

Made with Cursor


Note

Low Risk
Low risk: this is a TypeScript type-level change plus additional type tests; runtime behavior is unaffected, but it could subtly change inference/acceptance for code that relied on previous any propagation.

Overview
Fixes a TypeScript typing regression where subclassing RestEndpoint with O extends RestGenerics = any could cause any to be blocked by the searchParams conditional and yield overly restrictive URL-param/body types.

Adds an unknown extends O ? any : ... guard to both RestEndpoint and RestEndpointConstructorOptions to restore expected any behavior, and expands the TypeScript test to cover subclassed endpoints with both param and static paths (GET/POST) to ensure concrete body types remain accepted.

Written by Cursor Bugbot for commit 68b8b29. This will update automatically on new commits. Configure here.

@vercel
Copy link
Copy Markdown

vercel bot commented Apr 1, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs-site Ignored Ignored Preview Apr 1, 2026 10:52pm

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 1, 2026

⚠️ No Changeset found

Latest commit: 68b8b29

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 1, 2026

Size Change: 0 B

Total Size: 80.9 kB

ℹ️ View Unchanged
Filename Size
examples/test-bundlesize/dist/App.js 3.44 kB
examples/test-bundlesize/dist/polyfill.js 307 B
examples/test-bundlesize/dist/rdcClient.js 10.4 kB
examples/test-bundlesize/dist/rdcEndpoint.js 6.35 kB
examples/test-bundlesize/dist/react.js 59.7 kB
examples/test-bundlesize/dist/webpack-runtime.js 726 B

compressed-size-action

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 1, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.08%. Comparing base (9b6c7f4) to head (68b8b29).

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #3847   +/-   ##
=======================================
  Coverage   98.08%   98.08%           
=======================================
  Files         152      152           
  Lines        2871     2871           
  Branches      563      563           
=======================================
  Hits         2816     2816           
  Misses         11       11           
  Partials       44       44           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Add `unknown extends O ? any :` before the searchParams conditional in
RestEndpoint<O> and RestEndpointConstructorOptions<O>. When subclassing
with `O extends RestGenerics = any`, this catches O=any before it reaches
PathArgs, preventing the restrictive index-signature type.

Includes detailed comment explaining the partial inference limitation
where TypeScript may widen path literals to `string` due to complex
conditional constructor parameter types.

Follows up on #3845 which fixed PathArgs<any> but missed the higher-level
propagation through RestEndpointTypes.

Made-with: Cursor
@ntucker ntucker force-pushed the fix/pathargs-any-subclass-constructor branch from 13531fd to 68b8b29 Compare April 1, 2026 22:52
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