Skip to content

fix(rest): SoftPathArgs for widened path inference in RestEndpoint subclasses#3847

Merged
ntucker merged 5 commits intomasterfrom
fix/pathargs-any-subclass-constructor
Apr 3, 2026
Merged

fix(rest): SoftPathArgs for widened path inference in RestEndpoint subclasses#3847
ntucker merged 5 commits intomasterfrom
fix/pathargs-any-subclass-constructor

Conversation

@ntucker
Copy link
Copy Markdown
Collaborator

@ntucker ntucker commented Apr 1, 2026

Follows up on #3845.

Motivation

When subclassing RestEndpoint with O extends RestGenerics = any, TypeScript can widen path literals (e.g., '/users') to string during constructor inference. This caused PathArgs<string> to produce a restrictive index-signature type, which in turn created union overloads in ParamFetchWithBody. These unions made getOptimisticResponse, key, url, and process callbacks unassignable — their parameter types didn't match the union of possible argument tuples.

Additionally, endpoints with an explicit body but no method were defaulting to GET, making the body optional instead of required.

Solution

  • SoftPathArgs<P> — new utility type in pathTypes.ts that collapses PathArgs<string> to unknown (the identity for &), preventing the problematic union overloads while preserving full inference for literal paths.
  • Method inference from body — when body is explicitly provided and not undefined, RestEndpointConstructorOptions and RestEndpoint now infer POST as the default method for OptionsToBodyArgument, making the body required.
  • Legacy typesSoftPathArgs added to src-4.0-types/pathTypes.d.ts for TS 4.0 compatibility.
  • Comprehensive type tests covering:
    • All Parameters<F>-dependent callbacks (getOptimisticResponse, key, url, process) with widened paths
    • Widened paths with searchParams + body, params + body
    • .extend() on widened-path endpoints
    • resource() with AuthdEndpoint subclass + all extend patterns (per-endpoint, object form, function form)

Note

Medium Risk
Type-only changes to RestEndpoint inference could change TypeScript call signatures (e.g., body becoming required when method is omitted), potentially surfacing new compile errors in downstream code, though runtime behavior is unaffected.

Overview
Fixes TypeScript inference for RestEndpoint subclasses where path literals get widened to string, ensuring constructor callbacks like getOptimisticResponse, key, url, and process receive usable parameter types (including when searchParams: undefined is set).

Updates RestEndpoint typing to infer the default method from an explicitly provided body (treating it as POST), so body remains required across .extend() when method was omitted. Adds SoftPathArgs (including TS4.0 d.ts + playground types) and expands TypeScript tests to cover widened paths, subclassing, extend(), and resource() integration. Also fixes incorrect intra-blog links in the v0.15 release post.

Written by Cursor Bugbot for commit 3877777. 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.

Project Deployment Actions Updated (UTC)
docs-site Ready Ready Preview, Comment Apr 3, 2026 1:03am

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Apr 1, 2026

🦋 Changeset detected

Latest commit: 3877777

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 4 packages
Name Type
@data-client/rest Patch
example-benchmark-react Patch
test-bundlesize Patch
coinbase-lite Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another 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 (3877777).
⚠️ Report is 5 commits behind head on master.

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
…s constructors

Introduce SoftPathArgs<P> that resolves PathArgs<string> to `unknown`,
preventing union overloads in ParamFetchWithBody when path widens.
Infer method as POST when explicit body is provided.

Add comprehensive type tests for widened-path endpoints (all callback
overrides: getOptimisticResponse, key, url, process) and resource()
with AuthdEndpoint subclass (extend per-endpoint, object form,
function form).

Update src-4.0-types legacy replacement with SoftPathArgs export.

Made-with: Cursor
@ntucker ntucker changed the title fix(rest): Guard RestEndpoint against O=any in subclassed constructors fix(rest): SoftPathArgs for widened path inference in RestEndpoint subclasses Apr 3, 2026
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

@ntucker ntucker merged commit e93e820 into master Apr 3, 2026
26 checks passed
@ntucker ntucker deleted the fix/pathargs-any-subclass-constructor branch April 3, 2026 01:11
@github-actions github-actions bot mentioned this pull request Apr 3, 2026
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