Reading and Writing JSON with TypeScript

JavaScript Object Notation (JSON) has become the de facto standard for transferring data over the web due to its light-weight structure and simplicity. When using TypeScript, a statically typed superset of JavaScript, we can leverage JSON to build more reliable and effective applications.

This article will guide you on how to read and write JSON with TypeScript, cover common errors, and even improve your JSON handling with interfaces.

Writing JSON with TypeScript

Writing JSON in TypeScript is pretty straightforward as it leverages built-in JavaScript methods, mainly JSON.stringify(). This function transforms a JavaScript value into a JSON string.

Let's take a look at an example:

let user = {
    name: 'John Doe',
    age: 25,
    isAdmin: false,
};

let userJson = JSON.stringify(user);
console.log(userJson); // Output: {"name":"John Doe","age":25,"isAdmin":false}

In this code, we have a user object that we convert into a JSON string using JSON.stringify(). The output is a string representation of the user object.

Once we have the stringified JSON, we can then write it to various destinations, like an API response, a file, or something else. For example:

import fs from 'fs';

let user = {
    name: 'John Doe',
    age: 25,
    isAdmin: false,
};

let userJson = JSON.stringify(user);

fs.writeFile('user.json', userJson, (err) => {
    if (err) {
        console.log('Error writing file:', err);
    } else {
        console.log('Successfully wrote file');
    }
});

Reading JSON with TypeScript

Reading, or parsing, JSON in TypeScript also utilizes built-in JavaScript methods, specifically JSON.parse(). This function takes a JSON string and transforms it back into a JavaScript value or object.

Here's an example:

let userJson = '{"name":"John Doe","age":25,"isAdmin":false}';

let user = JSON.parse(userJson);
console.log(user); // Output: { name: 'John Doe', age: 25, isAdmin: false }

In this example, we have a JSON string userJson that we parse into a JavaScript object using JSON.parse().

Similar to our "writing" example earlier, the source of this JSON could be a number of things, like a user API request or a file. For example, if you wanted to read JSON from a file:

import fs from 'fs';

let user = {
    name: 'John Doe',
    age: 25,
    isAdmin: false,
};

let userJson = JSON.stringify(user);

fs.writeFile('user.json', userJson, (err) => {
    if (err) {
        console.log('Error writing file:', err);
    } else {
        console.log('Successfully wrote file');
    }
});

Error Handling in JSON Parsing and Stringification

When dealing with JSON, we must handle potential errors gracefully to prevent our applications from crashing. For instance, JSON.parse() can throw a SyntaxError if the string to be parsed is not valid JSON.

try {
    let user = JSON.parse('not a JSON string');
} catch (e) {
    console.log(e instanceof SyntaxError); // Output: true
    console.log(e.message); // Output: Unexpected token o in JSON at position 1
}

In this example, we tried parsing a string that wasn't valid JSON, which triggered a SyntaxError. The try/catch block allows us to catch the error and handle it appropriately.

Using Interfaces to Define JSON Structures in TypeScript

One of TypeScript's powerful features is its static typing system. This can be especially helpful when working with JSON data, as we can create interfaces to define the structure of our JSON objects. This provides better autocompletion, error checking, and readability.

For instance, consider the following interface:

interface User {
    name: string;
    age: number;
    isAdmin: boolean;
}

If we parse a JSON string into a User object, TypeScript will expect the object to adhere to the User interface structure.

let userJson = '{"name":"John Doe","age":25,"isAdmin":false}';

let user: User = JSON.parse(userJson);
console.log(user); // Output: { name: 'John Doe', age: 25, isAdmin: false }

However, TypeScript's compile-time type checking does not extend to runtime. Therefore, if a JSON string doesn't conform to the User interface, TypeScript won't throw an error at runtime.

let wrongUserJson = '{"name":"John Doe","isAdmin":false}';

let user: User = JSON.parse(wrongUserJson);
console.log(user); // Output: { name: 'John Doe', isAdmin: false }
Free eBook: Git Essentials

Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!

Here, the wrongUserJson string doesn't include an age property, but TypeScript doesn't throw an error when we assign the parsed JSON to the user object. To ensure data integrity at runtime, we need to manually validate the parsed JSON.

let wrongUserJson = '{"name":"John Doe","isAdmin":false}';

let user: User = JSON.parse(wrongUserJson);

if (!('age' in user)) {
    throw new Error('Invalid user data: age property missing');
}

In this example, we're checking whether the age property exists in the user object. If it doesn't, we throw an error. This is a simple example, and real-world applications might require more sophisticated data validation strategies.

Note: TypeScript interfaces are a compile-time construct and have no impact on the generated JavaScript. They solely exist to ensure type safety during development.

Conclusion

Handling JSON in TypeScript can be made incredibly effective and safe by utilizing TypeScript's static typing system and with native JSON parsing and stringification methods.

Proper error handling also plays an important role in creating error-free applications. Whether you're receiving data from an API or storing data in a file, understanding how to read and write JSON with TypeScript is a valuable skill for any developer.

Last Updated: July 27th, 2023
Was this article helpful?

Improve your dev skills!

Get tutorials, guides, and dev jobs in your inbox.

No spam ever. Unsubscribe at any time. Read our Privacy Policy.

Project

React State Management with Redux and Redux-Toolkit

# javascript# React

Coordinating state and keeping components in sync can be tricky. If components rely on the same data but do not communicate with each other when...

David Landup
Uchechukwu Azubuko
Details

Getting Started with AWS in Node.js

Build the foundation you'll need to provision, deploy, and run Node.js applications in the AWS cloud. Learn Lambda, EC2, S3, SQS, and more!

© 2013-2024 Stack Abuse. All rights reserved.

AboutDisclosurePrivacyTerms