DEV Community

Cover image for Strongly Typed JSON in TypeScript
Nick Taylor (he/him)
Nick Taylor (he/him)

Posted on • Updated on • Originally published at iamdeveloper.com

Strongly Typed JSON in TypeScript

Someone in one of the Slack communities I'm a part of asked today how to type JSON in TypeScript, specifically importing JSON and then typing it. They wondered if casting the JSON to unknown and then casting to a known type when consumed was a good approach.

The solution is not that complicated. We need to get our hands a little dirty and dig into the TypeScript compiler options for our project.

By default, if you import JSON, TypeScript will mention that it can't import it with the following error message:

Cannot find module './data.json'. Consider using '--resolveJsonModule' to import module with '.json' extension.ts(2732)

So TypeScript tells us what to do. Add the --resolveJsonModule flag. This is helpful if we're running the TypeScript CLI, but that is not what we're doing. What needs to be done is to add the resolveJsonModule key to the compiler options in the tsconfig.json file and set it to true.

{
  "compilerOptions": {
    "resolveJsonModule": true,
    // more awesome compiler options
  }
}
Enter fullscreen mode Exit fullscreen mode

Once that's done, you'll notice that if you type data., we have fully typed JSON data.

data variable in VS Code displaying autocomplete with properties of the data object

This is great for using data in a typed manner, but what if we needed the JSON type elsewhere in the project? We can create a type for it using typeof.

type PersonalInfo = typeof data;

The type PersonalInfo displaying its shape in CodeSandbox

You can play around with this CodeSandbox and have some fun seeing it all in action.

Discussion (15)

Collapse
nickytonline profile image
Nick Taylor (he/him) Author • Edited on

Yes, it works with arrays. If sone entries in the array were missing attributes, they would get typed as optional and depending on what you do, maybe even create union types.

Collapse
tonyvca profile image
Tony Henrique

Very cool!

Collapse
nickytonline profile image
Nick Taylor (he/him) Author

Amy Poehler and Seth Green high fiving on News Update

Collapse
harshhhdev profile image
Harsh Singh

This was needed! Saw this on Twitter, and I remember initially writing strongly typed JSON in TypeScript a long time, I was completely clueless and it took me a while to figure out.

Collapse
nickytonline profile image
Nick Taylor (he/him) Author

Captain America saluting

Collapse
marceloarraes profile image
Marcelo Arraes Teixeira

"export type PersonalInfo = typeof data;"
Didn't understand this line. I couldn't find anywhere the PersonalInfo was used. Would you be kind to explain why to make this export type PersonalInfo?

Collapse
nickytonline profile image
Nick Taylor (he/him) Author

Ahh, I don’t use it anywhere in the sample project. I was just mentioning that if you wanted to use the type for the exported JSON.

Collapse
dipayansukul profile image
Dipayan Sukul

Any good practice to load 25mb data from postgres db using nestjs?

Collapse
nickytonline profile image
Nick Taylor (he/him) Author

The reason it’s a compiler option is because it can slow down the compiler for large data. You might be better off using a codegen tool to generate the types for that large JSON file.

Read big JSON files? #42761

Bug Report

🔎 Search Terms

"large json files"

Problem

None of the predefined sections are relevant here.

I'm trying to get types from a JSON file using resolveJsonModule. I'm using VS Code to do everything here. My JSON file is 4.9 MB and 200k lines. When I try to inspect the result of require('./big-file.json), it says {}. But it works great for another smaller file, albeit a bit slow.

Not sure if this is relevant or not, but it also fails for this big file in quicktype and works for the slightly smaller file. I assumed they're using TypeScript's parser/compiler under the hood, which would explain it. If they're not, then maybe it's a Node.js limitation that it's coming across.

To be clear, the require call itself works fine and returns a valid JSON object. So it might not be a Node.js memory limitation issue. But it might be one if TypeScript is more than doubling the memory by all its type analysis, or by duplicating substrings, etc.

Just some thoughts. I have no idea what's going on. All I know is that I was hoping VS Code would analyze my JSON files for me, but it's only working on some files.

Specifically this comment.

Collapse
mrfaizanshariff profile image
Mohammed Faizan Shariff

JSON using typescript, can it be called TYSON?

Collapse
nickytonline profile image
Nick Taylor (he/him) Author

Mike Tyson laughing

Collapse
karfau profile image
Christian Bewernitz

I came here expecting an article about having "type safe JSON at runtime", but this is just about JSON data that is already known at compile time.

Collapse
nickytonline profile image
Nick Taylor (he/him) Author • Edited on

Typically what folks do for APIs is generate the types for the different JSON returned.

Here’s an example from Apollo.

And here's another post on how to to do this, stefanwille.com/2021/05/2021-05-30...

Here's another project called restful-react

GitHub logo contiamo / restful-react

A consistent, declarative way of interacting with RESTful backends, featuring code-generation from Swagger and OpenAPI specs 🔥

restful-react

npm

⚠️ restful-react will soon be deprecated: We are working on a new open api generator that generates react-query components: github.com/fabien0102/openapi-codegen ⚠️

Building React apps that interact with a RESTful API presents a set of questions, challenges and potential gotchas. This project aims to remove such pitfalls, and provide a pleasant developer experience when crafting such applications.

It can be considered a thin wrapper around the fetch API in the form of React components and hooks.

When used in a setup with OpenAPI / Swagger specs and Typescript, restful-react ensures a reliable and always up to date contract between backend and frontend. It generates components and types from your specs and can be integrated quite comfortably into your development workflows (featuring for example the import of OpenAPI specs from your github repos).

restful-react is very well tested, production ready and powers all of our projects at Contiamo.

And here it is being demoed.

I'm sure there's others.