Potential Solution for Support for Tagged Types in `ParseJSON` Type
I just wanted to post this here since it would very likely get missed since it is an old post, and I figure here might be a more reasonable place to get an answer:
https://github.com/TanStack/router/issues/4005#issuecomment-3327007509
Effectively, I have an approach with Interface merging that may enable the router to support parsing tagged types at a type level, where currently it instead treats them as non-stringifiable and requires a patch for any given tagged/opaque type implementation.
My main questions are:
1. Given my solution provided in the GitHub thread, is this something conceptually that Tanstack would like to pursue
(I can see the argument that the "API" of such functionality is quite complicated for a majority of developers, but on the other hand, could be put at the bottom of the typescript docs section, and effectively requires 0 attention from people that do not require the functionality)
2. If this is an API that would be useful, would you like me to create a PR
(Don't want to go ahead with that if it's just going to waste people's time, so thought I should clarify first)
3. I have a suspicion that this could have the potential to add some typescript performance overhead since it requires an
infer
which I roughly understand to be a more "expensive" operation in typescript (at least from my current knowledge level) and therefore. Is this something that I can realistically verify while making a PR, or is it more of a "yolo" situation?
Note: I am posting here, but this fix would apply for both start and router since it modifies the underlying ParseJSON
type if I were to go ahead with it.GitHub
Missing support for Tagged types in Server Function response · Iss...
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: ...
8 Replies
rare-sapphire•7d ago
at least this seems to work now: https://github.com/TanStack/router/issues/3157
GitHub
types: createServerFn does not accept branded strings · Issue #315...
Which project does this relate to? Start Describe the bug Code: export const listWidgets = createServerFn({ method: "GET" }).handler( async () => { return [ { id: "1" as stri...
stormy-goldOP•7d ago
Interesting, I’m surprised that didn’t work originally since it only used primitives.
The main problem with most branded types is that they rely on symbols. Outside of type-fest, tanstack queries QueryKey made using queryOption also suffers from this issue.
What are your thoughts on this approach? I think it would require a “Register<T>” interface that is provided from tanstack end
rare-sapphire•7d ago
can you provide a full example that currently does not work?
stormy-goldOP•7d ago
I've updated the repro with this example as well now:
https://stackblitz.com/edit/tanstack-router-op1tmyk6?file=src%2Futils%2Faccount.tsx
For clarity, I fully expect the type to tell me that it's not serializable, since most tagged typed implementations use a symbol as a key which is not serializable, my suggestion for a fix is just a way for consumers to explicitly handle specific tagged type implementations so they do not need to disable the serializable check throughout the code base, and instead have an actual way to work around the problem.
The updated example includes it working for a primitive, but not for a
type-fest
tagged type, as well as for a Tanstack query queryKey.sStackBlitz
Tanstack serverFn with Tagged types (duplicated) - StackBlitz
Run official live example code for Router Start Basic, created by Tanstack on StackBlitz
stormy-goldOP•7d ago
Just to simplify my question:
In my opinion, the only way for the router to support tagged types is to offer a generic register interface that can have a
unwrap
or unwrappedTag
key on it that can be used within the ParseJSON function. I suspect this would basically involve Tanstack having an interface on top of the base Register
interface
Then for consumers to use this to support specific tagged types, they would essentially write an unwrap
type and register it on the interface
Is this something you would like me to implement and make a PR for so that users can have tagged type support, or is this interface/API for supporting it too "clunky" for something exposed to the user? I think implementing it will be pretty straight forward, especially given the scope for now can be limited to the ParseJSON
type, so happy to make a PR, I just wanted to clarify if this is even something that you wantrare-sapphire•6d ago
using latest start version i dont get a type error in your example. can you please check?
stormy-goldOP•6d ago
I apologize for wasting your time, I should've checked the latest router version... This can probably just be ignored then.
I do want to clarify though -Is it actually possible to send symbols from the server to the client? I understand that it's not giving a type error - but I would expect that it should be impossible to actually send a symbol over the wire - since it is unique. Is this actually handled by Tanstack start?
rare-sapphire•6d ago
you can use a custom serialization adapter if you want to actually handle symbols at runtime