DEV Community

Cover image for Safely use `JSON.parse()` in TypeScript
Muhammad A Faishal
Muhammad A Faishal

Posted on • Updated on

Safely use `JSON.parse()` in TypeScript

Let's talk about something that most of us can relate to: JSON.parse(). We all know that thing we use to turn a JSON string into an object.

const jsonString = '{ "title": "Title" }'

const jsonValue = JSON.parse(jsonString)
// { title: 'Title' } ✅
Enter fullscreen mode Exit fullscreen mode

Problems

Now, here's the thing...

Have you ever wondered what happens when you mess around with the value of jsonString? Let's say you change '{ "title": "Title" }' to ''. Well, guess what? The expected turns into... ERROR! 🤯

const jsonString = ''

const jsonValue = JSON.parse(jsonString)
// Error: Unexpected end of JSON input ❌ 💣
Enter fullscreen mode Exit fullscreen mode

It may seems like a small issue, but guess what? Lots of developers forget to handle it properly!

Now, here's the interesting part...

In TypeScript, JSON.parse() doesn't have any specific type arguments. It just returns any. This means, it comes at the cost of losing the benefits of static typing and type safety.

const jsonString = "";

const jsonValue = JSON.parse(jsonString)
// const jsonValue: any ❌
Enter fullscreen mode Exit fullscreen mode

When developers treat potentially unsafe data as completely safe, it can cause some really frustrating errors to deal with. 😫

Solutions

But don't worry, I've got a couple of solutions! 💡

1. Create "safeJsonParse" function

const safeJsonParse = <T>(str: string) => {
  try {
    const jsonValue: T = JSON.parse(str);

    return jsonValue;
  } catch {
    return undefined;
  }
};
// const safeJsonParse: <T>(str: string) => T | undefined ✅
Enter fullscreen mode Exit fullscreen mode

This function is responsible for handling parsing errors. If an error occurs during parsing, it will return undefined. Otherwise, it will return the parsed JSON value along with its corresponding data type.

2. Add fallback

interface JsonValue {
  title: string
}

const jsonString = '{ "title": "Title" }'

const jsonValue = safeJsonParse<JsonValue>(jsonString) || { "title": "" }
// const jsonValue: JsonValue ✅
Enter fullscreen mode Exit fullscreen mode

Just in case the value is undefined, we can add a fallback mechanism. This ensures that the value will always be provided, regardless of what happens.

Conclusion

So, if we keep these things in mind, we'll avoid headaches and make our code super solid. I hope you find these tips useful for your projects! You got this! ✨

Top comments (3)

Collapse
 
ant_f_dev profile image
Anthony Fung

I would have thought an empty string for jsonString would indicate an error somewhere else, and as such, it's a good thing for it to fail 'loudly'. That way, you can quickly see where the error is by looking at the error callstack in the browser dev tools - and then avoiding the parse for invalid JSON.

I get that you'd want the parsed object typed though, so great thinking on the safeJsonParse function.

Collapse
 
tkustov profile image
Taras Kustov

Try zod, its really cool

Collapse
 
maafaishal profile image
Muhammad A Faishal

Yeah. Once you're aware of this potential issue, leveraging Zod makes your code more robust