How to Parse a JSON String into an Object

A guide on how to safely convert a JSON string into a TypeScript object using JSON.parse() in both browser and Node.js environments.

It’s common to get data as a JSON string, whether it’s from a data-* attribute in HTML, a file on your server, or an API response. You need to parse this string to turn it into a usable JavaScript object.

Example: Reading from a data-* Attribute

Let’s say you have a search input with some filter data stored as a JSON string in a data-filter attribute.

HTML
<input
    id="search-input"
    type="text"
    placeholder="Search"
    data-filter='{"cookbook": "typescript"}'
/>

You can get the string from the dataset property and then use JSON.parse() to convert it.

TypeScript
const searchInput = document.querySelector<HTMLInputElement>("#search-input");

let filters = {};
if (searchInput?.dataset.filter) {
    try {
        filters = JSON.parse(searchInput.dataset.filter);
    } catch (error) {
        console.error("Failed to parse data-filter JSON:", error);
    }
}

console.log("Filters object:", filters);
// Expected output: { cookbook: "typescript" }

Example: Reading a JSON File

In a Node.js environment, you often get JSON strings from reading files.

Let’s say you have a config.json file:

JSON
{
    "port": 8080,
    "host": "localhost"
}

You can read and parse this file like this:

TypeScript
import { readFileSync } from "fs";

let config = {};
try {
    const fileContent = readFileSync("config.json", "utf-8");
    config = JSON.parse(fileContent);
} catch (error) {
    console.error("Failed to read or parse config.json:", error);
}

console.log("Config object:", config);
// Expected output: { port: 8080, host: "localhost" }

The main tool for this is the built-in JSON.parse() function, which works in both the browser and Node.js. It’s important to always wrap it in a try...catch block, because it will throw an error if the string is not valid JSON, which could crash your script.

By default, JSON.parse() returns a value of type any. If you know what the structure of the object should be, you can add type safety by using a type assertion or a library like Zod.

Here is a simple example with a type assertion:

TypeScript
interface AppConfig {
    port: number;
    host: string;
}

let config: AppConfig | {} = {};
try {
    const fileContent = readFileSync("config.json", "utf-8");
    config = JSON.parse(fileContent) as AppConfig;
} catch (error) {
    // ...
}