Skip to content

TypeScript Type Inference Issue with createServerFn and beforeLoad using Connect RPC #5788

@EdiAfremovFactify

Description

@EdiAfremovFactify

Which project does this relate to?

Start

Describe the bug

Problem:
I'm experiencing a TypeScript type inference issue when using createServerFn().handler() and beforeLoad with a Connect RPC function that returns a discriminated union response type.

Code example:

// My Connect RPC response type (discriminated union)
type ConnectRpcResponse<TData extends Message> = 
  | { readonly data: TData; readonly error?: undefined; }
  | { readonly data?: undefined; readonly error: ConnectError; };

// My getCurrentUser function returns this type
export async function getCurrentUser(
  payload: ConnectRpcRequestPayload<GetCurrentUserRequest>
): Promise<ConnectRpcResponse<UserAccountDetails>> {
  // ... implementation
  return { data: response.account.value }; // UserAccountDetails
}

// Trying to use it with createServerFn
const getCurrentUserFn = createServerFn({ method: 'GET' }).handler(async function() {
  const data = await getCurrentUser({});
  return data; // ❌ TypeScript error here 
});

Actual Behavior:
TypeScript recursively infers the entire getCurrentUser response structure, deeply expanding all nested Protobuf Message types within the discriminated union.
This results in a massive inferred type that is not assignable to UserAccountDetails, causing a type error and Cursor IDE to completely hang/freeze, making the file unusable.

Environment:
@tanstack/react-start
Connect RPC with Protobuf messages
TypeScript

Your Example Website or App

N/A

Steps to Reproduce the Bug or Issue

Local

Expected behavior

The handler should infer the return type as ConnectRpcResponse<UserAccountDetails>.

Screenshots or Videos

Image

Platform

  • Start Version: start 1.134.10
  • OS: macOS
  • Bundler: vite
  • Bundler Version: 7.1.12

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions