You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A JSON<T> utility type, where T is a record type of any shape and the output would be what you would get from JSON.parse(JSON.stringify(t)).
I would expect that Map and Set would be gone, Date would turn into String etc.
📃 Motivating Example
In full-stack frameworks like Next.js or Remix, you usually have a method for fetching data from the database to provide it to your route components. When doing a client-side transition, you need to call this method and transport using JSON. This is why Next.js has a lint rule for returning JSON-unsafe data from getServerSideProps.
Using this utility type you could ignore this warning and work with whatever you get from the JSON in the component.
💻 Use Cases
Using this utility type you could ignore the warning and work with whatever you get from the JSON in the component.
My current alternative is using superjson as a babel plugin.
It's possible to write this type in userland; we don't add type aliases unless they're required for declaration emit since people have different opinions about the "right" way to declare these types.
BigInt should make the whole thing to error out (returning never) but it's not possible
There may be other edge cases I'm simply not aware of
The current situation is not great when I get records with createdAt/updatedAt from Prisma and serialize with Remix/Next.js. I lose type safety as the Dates are in fact strings. People working with Fauna probably have it worse, as TypeScript mistakenly shows methods that don't survive serialization.
Superjson is a solution like I mentioned, but you pay the price in more dependencies shipped to the client, serialization/deserialization runtime cost, and larger JSON payload.
Since we already have an Awaited helper type that could actually be implemented in userland, I'm hopeful this might be added at some point in the future.
Michaël De Boey (@MichaelDeBoey) I tried to do a thorough research to find such a helper so didn't have to write one myself, but I seem to have somehow missed that. 😅 I need to do some testing (there are a lot of edge cases!) but it looks promising!
By the way, regardless of my evaluation, there's no way it can solve the NaN problem so changes on the TypeScript side is still needed to ensure there's a robust solution.
Fatih Altinok (@frontsideair) I would suggest you to add an issue on the repo for that then.
I've seen some pretty amazing things @sidresorhus has done with the types, so wouldn't be surprised if he came up with a solution for your problem.
I tried my best to support all edge cases, but the issues I mentioned still remain, mainly the NaN issue. I researched it extensively and and it doesn't seem like it's possible to fix in userland. (Infinity, on the other hand, was possible to support, although in a hacky way.)
Hi Fatih Altinok (@frontsideair), I've found your comment by chance while bumping into this TypeScript issue myself.
Just wanted to share that now Remix supports the single-fetch API, so you no longer need to serialise object values like Date and BigInt to JSON yourself :)
Activity
RyanCavanaugh commentedon Apr 15, 2022
It's possible to write this type in userland; we don't add type aliases unless they're required for declaration emit since people have different opinions about the "right" way to declare these types.
frontsideair commentedon Jun 24, 2022
I have written a utility type for this, but it's not possible to write a robust one in userland, for a few reasons:
NaNliteral does not exist: Add a --strictNaNChecks option, and a NaN / integer / float type to avoid runtime NaN errors #28682BigIntshould make the whole thing to error out (returningnever) but it's not possibleThe current situation is not great when I get records with createdAt/updatedAt from Prisma and serialize with Remix/Next.js. I lose type safety as the
Dates are in factstrings. People working with Fauna probably have it worse, as TypeScript mistakenly shows methods that don't survive serialization.Superjson is a solution like I mentioned, but you pay the price in more dependencies shipped to the client, serialization/deserialization runtime cost, and larger JSON payload.
Since we already have an
Awaitedhelper type that could actually be implemented in userland, I'm hopeful this might be added at some point in the future.MichaelDeBoey commentedon Jun 24, 2022
Fatih Altinok (@frontsideair) The
type-festlibrary has already implemented aJsonifyhelper.Maybe that one could help you out?
https://github.com/sindresorhus/type-fest#json
frontsideair commentedon Jun 25, 2022
Michaël De Boey (@MichaelDeBoey) I tried to do a thorough research to find such a helper so didn't have to write one myself, but I seem to have somehow missed that. 😅 I need to do some testing (there are a lot of edge cases!) but it looks promising!
By the way, regardless of my evaluation, there's no way it can solve the
NaNproblem so changes on the TypeScript side is still needed to ensure there's a robust solution.MichaelDeBoey commentedon Jun 25, 2022
Fatih Altinok (@frontsideair) I would suggest you to add an issue on the repo for that then.
I've seen some pretty amazing things @sidresorhus has done with the types, so wouldn't be surprised if he came up with a solution for your problem.
MichaelDeBoey commentedon Jun 30, 2022
type-festnow has an updatedJsonifygeneric.https://github.com/sindresorhus/type-fest/releases/tag/v2.15.0
frontsideair commentedon Jun 30, 2022
I tried my best to support all edge cases, but the issues I mentioned still remain, mainly the
NaNissue. I researched it extensively and and it doesn't seem like it's possible to fix in userland. (Infinity, on the other hand, was possible to support, although in a hacky way.)typescript-bot commentedon Jun 21, 2023
This issue has been marked as "Out of Scope" and has seen no recent activity. It has been automatically closed for house-keeping purposes.
jkomyno commentedon May 16, 2024
Hi Fatih Altinok (@frontsideair), I've found your comment by chance while bumping into this TypeScript issue myself.
Just wanted to share that now Remix supports the
single-fetchAPI, so you no longer need to serialise object values likeDateandBigIntto JSON yourself :)See docs: https://remix.run/docs/en/main/guides/single-fetch#streaming-data-format.
frontsideair commentedon May 16, 2024
Alberto Schiabel (@jkomyno) yeah I’ve been following closely and pretty excited about this! Up until now I happily used
remix-typedjsonby the way.