Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@mtt-artis
Copy link

@mtt-artis mtt-artis commented Jan 28, 2026

Hi 👋

This change allows serverFn inputValidator to accept either typed data or FormData while continuing to share a single input schema.

In practice, some call sites naturally work with typed objects (e.g. programmatic mutations), while others already have FormData available (e.g. form submissions). Today, supporting both requires extra boilerplate or duplicate serverFn.

My goal is to reduce friction when integrating serverFn with form-driven workflows (including TanStack DB - i like to share schema between thoses libs) while keeping type safety intact.

Thanks

Summary by CodeRabbit

  • Bug Fixes

    • Type validation now supports FormData alongside serializable input for POST requests while preserving method-specific validation rules.
  • Tests

    • Added cases covering FormData union behavior for POST and ensuring GET validations disallow FormData unions; added tests for non-serializable inputs in POST scenarios.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 28, 2026

📝 Walkthrough

Walkthrough

The PR changes the type-level conditional in ValidateValidatorInput for POST requests to detect FormData via Extract<ResolveValidatorInput<TInputValidator>, FormData> extends never, enabling a FormData union branch alongside a serializable branch. Three type tests were added covering POST/GET and non-serializable unions.

Changes

Cohort / File(s) Summary
Type validation logic
packages/start-client-core/src/createServerFn.ts
Updated ValidateValidatorInput<TRegister, TMethod, TInputValidator>: POST branch now checks Extract<ResolveValidatorInput<TInputValidator>, FormData> extends never and returns either a FormData path or a serializable-validated path, instead of the previous single conditional ResolveValidatorInput<TInputValidator> extends FormData.
Type tests
packages/start-client-core/src/tests/createServerFn.test-d.ts
Added three type-level tests: POST accepting `FormData

Sequence Diagram(s)

(omitted — change is type-level and does not introduce multi-component runtime control flow)

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

Suggested reviewers

  • chorobin

Poem

🐰 A rabbit nudged the types today,
Checking FormData the careful way,
POST learns two paths to roam,
GET keeps to its serializable home,
Hops of tests to guide the play.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(createServerFn): allow FormData union type' directly and clearly describes the main change—enabling FormData as a union type option in createServerFn's inputValidator.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing touches
  • 📝 Generate docstrings

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
Contributor

@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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/start-client-core/src/createServerFn.ts (1)

466-480: Guard against overly broad POST validator inputs.

Line 471 checks FormData extends ResolveValidatorInput<TInputValidator>, which incorrectly treats supertypes of FormData (e.g., object, {}, unknown, any) as "FormData-capable" and skips ValidateSerializable validation. This allows non-serializable inputs to bypass validation on POST requests. Detect FormData membership in the resolved type instead using Extract:

Type refinement
 export type ValidateValidatorInput<
   TRegister,
   TMethod extends Method,
   TInputValidator,
 > = TMethod extends 'POST'
-  ? FormData extends ResolveValidatorInput<TInputValidator> 
-    ? ResolveValidatorInput<TInputValidator>
-    : ValidateSerializable<
-        ResolveValidatorInput<TInputValidator>,
-        RegisteredSerializableInput<TRegister>
-      >
+  ? [Extract<ResolveValidatorInput<TInputValidator>, FormData>] extends [never]
+    ? ValidateSerializable<
+        ResolveValidatorInput<TInputValidator>,
+        RegisteredSerializableInput<TRegister>
+      >
+    : FormData | ValidateSerializable<
+        Exclude<ResolveValidatorInput<TInputValidator>, FormData>,
+        RegisteredSerializableInput<TRegister>
+      >
   : ValidateSerializable<
       ResolveValidatorInput<TInputValidator>,
       RegisteredSerializableInput<TRegister>
     >

Add a type test like FormData | { func: () => void } to prevent regressions.

@mtt-artis mtt-artis marked this pull request as draft January 28, 2026 22:38
@mtt-artis mtt-artis marked this pull request as ready for review January 28, 2026 23:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant