Skip to content

Missing support for Tagged types in Server Function response #4005

@bm-vs

Description

@bm-vs

Which project does this relate to?

Start

Describe the bug

If a server function response includes a Tagged/Branded type

type AccountId = Tagged<string, 'AccountId'>

declare const tag: unique symbol;
type AccountIdExpanded = string & {readonly [tag]: 'AccountId'}

the TS compiler fails to resolve the response type, and the handler function gets flagged as invalid, even if the underlying type is a primitive.

Your Example Website or App

https://stackblitz.com/edit/tanstack-router-swedhutz?file=src%2Futils%2Faccount.tsx&view=editor

Steps to Reproduce the Bug or Issue

  1. Create a Tagged type
  2. Create a server function
  3. Return a variable of that type from the server function

Expected behavior

When returning data that includes Tagged types, the output of server functions should be correctly inferred, and Typescript shouldn't flag any errors.

Screenshots or Videos

No response

Platform

  • OS: macOS
  • Browser: Firefox
  • Version: 137.0.1

Additional context

I'm using Tagged/Branded types extensively in my project to make the type system more robust.

Example:

export type AccountId = Tagged<string, 'AccountId'>;
export type AccountVersionId = Tagged<string, 'AccountVersionId'>;
export type AccountUrl = Tagged<string, 'AccountUrl'>;

The problem I've run into is that, when the response includes one of these types, the field gets flagged as "unserializable" by the TS compiler:

The types of 'data.id.toString' are incompatible between these types.
    Type '() => string' is not assignable to type '"Function is not serializable"'.

This happens because the id field is no longer just a primitive type, but a union with {[k: symbol]: string}.


I traced this backed to the SerializerStringifyBy type in the router-core package and, by extension, the Serializable type on l.28.

If Serializable became Date | undefined | Error | FormData | bigint | string the check on l.8 would pass and make the serialization types support Tagged types (at least for strings, adding number broke the tests).


I get that this is a quite niche use case.

So, for anyone that runs into this, my temporary workaround was to use pnpm patchpnpm patch @tanstack/router-core and change the Serializable type to:

export type Serializable = Date | undefined | Error | FormData | bigint | string

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