Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JSON<T> utility type #48697

Closed
5 tasks done
frontsideair opened this issue Apr 14, 2022 · 10 comments
Closed
5 tasks done

JSON<T> utility type #48697

frontsideair opened this issue Apr 14, 2022 · 10 comments
Labels
Out of Scope This idea sits outside of the TypeScript language design constraints Suggestion An idea for TypeScript

Comments

@frontsideair
Copy link

Suggestion

🔍 Search Terms

json, jsonify

✅ Viability Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.

⭐ Suggestion

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.

@RyanCavanaugh RyanCavanaugh added Suggestion An idea for TypeScript Out of Scope This idea sits outside of the TypeScript language design constraints labels Apr 15, 2022
@RyanCavanaugh
Copy link
Member

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
Copy link
Author

frontsideair commented 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:

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.

@MichaelDeBoey
Copy link

@frontsideair The type-fest library has already implemented a Jsonify helper.
Maybe that one could help you out?

https://github.com/sindresorhus/type-fest#json

@frontsideair
Copy link
Author

frontsideair commented Jun 25, 2022

@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.

@MichaelDeBoey
Copy link

@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
Copy link

type-fest now has an updated Jsonify generic.
https://github.com/sindresorhus/type-fest/releases/tag/v2.15.0

@frontsideair
Copy link
Author

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.)

@typescript-bot
Copy link
Collaborator

This issue has been marked as "Out of Scope" and has seen no recent activity. It has been automatically closed for house-keeping purposes.

@typescript-bot typescript-bot closed this as not planned Won't fix, can't repro, duplicate, stale Jun 21, 2023
@jkomyno
Copy link

jkomyno commented May 16, 2024

Hi @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 :)

See docs: https://remix.run/docs/en/main/guides/single-fetch#streaming-data-format.

@frontsideair
Copy link
Author

@jkomyno yeah I’ve been following closely and pretty excited about this! Up until now I happily used remix-typedjson by the way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Out of Scope This idea sits outside of the TypeScript language design constraints Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

5 participants