Skip to content

feat(types)!: remove TypeBox schema type inference#54

Merged
halvaradop merged 3 commits into
masterfrom
feat/remove-typebox
Jun 5, 2026
Merged

feat(types)!: remove TypeBox schema type inference#54
halvaradop merged 3 commits into
masterfrom
feat/remove-typebox

Conversation

@halvaradop
Copy link
Copy Markdown
Member

@halvaradop halvaradop commented Jun 5, 2026

Description

This pull request removes TypeBox-based type inference for the searchParams, params, and body fields from the client functions returned by createClient.

Previously, these types were inferred using TypeBox's Static type. However, Static introduces a significant amount of type-level computation and has proven to be extremely expensive for TypeScript performance. To reduce the number of type instantiations and improve compile-time performance, this PR removes the use of Static from the client implementation while preserving runtime schema validation.

The client type system still infers whether searchParams, params, or body are required for a given endpoint. However, it no longer infers the individual fields within those objects.


In #52, TypeBox-based inference for searchParams, params, and body was removed from middleware and handler contexts based on the diagnostics performed in that pull request. However, during the investigation in aura-stack-ts/auth#179, it was discovered that client.ts was still responsible for a large number of expensive type operations due to the remaining usage of TypeBox's Static type.

Diagnostic Results

The following results show the number of TypeScript instantiations after the changes introduced by this PR:

  • 22,388src only
  • 44,349src and bench
  • 167,707src, bench, and test

Usage

const getItem = createEndpoint(
  "GET",
  "/items/:itemId",
  (ctx) => {
    return ctx.json({ method: ctx.method })
  },
  {
    schemas: {
      params: typebox.Object({
        itemId: typebox.String(),
      }),
    },
  }
)

const router = createRouter([getItem])

const client = createClient<typeof router>({
  baseURL: "http://api.example.com",
})

client.get("/items/:itemId", {
  // Infers that params is required,
  // but does not infer the fields inside the object.
  params: {
    itemId: "123",
  },
})

Related PRs

BREAKING CHANGE: Automatic type inference from TypeBox schemas has been removed.
Runtime schema validation remains supported.
@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 5, 2026

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

Project Deployment Actions Updated (UTC)
router Ready Ready Preview, Comment Jun 5, 2026 1:24am

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 5, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

The "typebox" branch of InferSchema now resolves to {} and the typebox type-only import was removed. Tests add a GET /items endpoint to exercise TypeBox client inference, and CHANGELOG entries document removal of TypeBox Static compile-time inference while keeping runtime validation.

Changes

TypeBox Schema Type Inference

Layer / File(s) Summary
InferSchema TypeBox branch simplification
src/@types/client.ts
The "typebox" conditional branch of InferSchema<T, Kind> changes from Static<T & TSchema> to {} and the typebox type-only import is removed; a blank line is added before the Client doc comment.
TypeBox client test router update
test/client.test.ts
Adds a new GET /items endpoint to the TypeBox test router so client type inference assertions exercise the updated router surface.
CHANGELOG updates
CHANGELOG.md
Adds entries to “Unreleased” and 0.7.1 noting removal of TypeBox Static-based compile-time inference for searchParams, params, and body, while runtime TypeBox validation remains supported.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • aura-stack-ts/router#52: Both PRs remove/disable TypeBox-based compile-time type inference by changing the TypeBox schema-to-TypeScript mapping (e.g., InferSchema/UnwrapSchema no longer rely on typebox's Static helpers).
  • aura-stack-ts/router#48: Related changes to TypeBox schema handling and inference across router/validation types that overlap the client inference adjustments.
  • aura-stack-ts/router#51: Overlapping edits to InferSchema and TypeBox-related type inference logic.

Suggested labels

enhancement

Poem

🐰 I hopped through types both near and wide,
TypeBox Static waved, then sighed,
Now {} returns where Static stood,
Tests updated—everything's good.
A rabbit cheers for tidy types!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(types)!: remove TypeBox schema type inference' accurately reflects the main change: removal of TypeBox schema type inference, which is demonstrated across all modified files (type definition change, test updates, and changelog documentation).
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/remove-typebox

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.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
test/client.test.ts (1)

565-569: ⚡ Quick win

Use a single @ts-expect-error on the call expression, not per object property.

Property-level directives here are brittle to TypeScript diagnostic-location changes and can produce noisy “unused @ts-expect-error” failures. Prefer one directive on the client.delete(...) call.

Suggested change
-    const deletedItem = await client.delete("/items/:itemId", {
-        // `@ts-expect-error` invalid typebox support.
-        params: { itemId: "123" },
-        // `@ts-expect-error` invalid typebox support.
-        searchParams: { force: "true" },
-    })
+    // `@ts-expect-error` invalid typebox support.
+    const deletedItem = await client.delete("/items/:itemId", {
+        params: { itemId: "123" },
+        searchParams: { force: "true" },
+    })
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/client.test.ts` around lines 565 - 569, The test uses multiple
property-level `@ts-expect-error` comments on the params and searchParams objects
which is brittle; instead place a single `@ts-expect-error` on the
client.delete(...) call expression. Update the test so the invalid TypeBox types
remain suppressed by one directive applied to the call to client.delete
(referencing the client.delete(...) invocation and the params/searchParams
objects) rather than per-property comments.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/`@types/client.ts:
- Around line 12-13: InferSchema currently maps Kind extends "typebox" to T (the
TypeBox schema type) which causes InferContent to treat schema metadata as the
runtime payload; change the TypeBox branch to return unknown instead of T so
TypeBox schemas don't lock the client API to the schema type. Update the
conditional in InferSchema (the branch checking Kind extends "typebox") to use
unknown, and ensure any downstream usage in InferContent that composes
params/searchParams/body (the types that consume InferSchema) still expects the
runtime shape (now unknown) rather than T.

---

Nitpick comments:
In `@test/client.test.ts`:
- Around line 565-569: The test uses multiple property-level `@ts-expect-error`
comments on the params and searchParams objects which is brittle; instead place
a single `@ts-expect-error` on the client.delete(...) call expression. Update the
test so the invalid TypeBox types remain suppressed by one directive applied to
the call to client.delete (referencing the client.delete(...) invocation and the
params/searchParams objects) rather than per-property comments.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7791114a-cf3c-4a50-aafe-eb936a69d37f

📥 Commits

Reviewing files that changed from the base of the PR and between fd5c511 and ba13f4e.

📒 Files selected for processing (2)
  • src/@types/client.ts
  • test/client.test.ts

Comment thread src/@types/client.ts Outdated
@halvaradop halvaradop merged commit e1ff1c9 into master Jun 5, 2026
6 checks passed
@halvaradop halvaradop deleted the feat/remove-typebox branch June 5, 2026 01:45
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