Question

How to Parse a JSON String in TypeScript

typescriptjavascriptjsonstring

Question

Is there a TypeScript equivalent of JavaScript's JSON.parse() for converting a JSON string into an object?

For example, given this JSON string:

const jsonText = '{"name":"Bob","error":false}';

how can it be parsed and used safely in TypeScript?

Short Answer

TypeScript uses the same JSON.parse() function as JavaScript because TypeScript compiles to JavaScript. The important extra step is handling the parsed value safely: JSON.parse() returns any, so use a type assertion only when the input is trusted, or validate external data before relying on its shape.

Concept

TypeScript is a superset of JavaScript, which means normal JavaScript APIs are available in TypeScript. Therefore, parsing JSON works exactly the same way:

const value = JSON.parse(text);

JSON.parse() converts a JSON-formatted string into JavaScript values:

  • A JSON object becomes a JavaScript object.
  • A JSON array becomes a JavaScript array.
  • JSON strings, numbers, booleans, and null become their matching JavaScript values.

The key TypeScript detail is the return type. JSON.parse() is typed as returning any. TypeScript cannot know whether a string received from an API, a file, or browser storage really contains the properties your program expects.

For example, this compiles but can fail at runtime:

interface User {
  name: string;
  error: boolean;
}

const user = JSON.parse('{"unexpected":123}') as User;
console.log(user.name.toUpperCase()); // Runtime error: name is undefined

A type assertion tells the TypeScript compiler what you expect, but it does not inspect or validate the parsed data. Use assertions for known, controlled JSON. For external or untrusted data, check its structure before using it.

Mental Model

Think of JSON as a sealed delivery box containing data written in a standard format.

  • JSON.parse() opens the box and turns its contents into a JavaScript value.
  • A TypeScript interface is the delivery label that says what you expect to find inside.
  • Writing as User does not inspect the box. It only tells TypeScript, “Treat this as a User.”
  • Validation is the actual inspection step: you open the box and confirm it contains the expected fields with the expected types.

This distinction matters because TypeScript types disappear when your code runs. Runtime data still needs runtime checks.

Take Quiz

Syntax and Examples

Use JSON.parse() with a valid JSON string:

const jsonText = '{"name":"Bob","error":false}';
const data = JSON.parse(jsonText);

console.log(data.name);  // Bob
console.log(data.error); // false

The result is a JavaScript object. To describe the expected structure, create an interface:

interface ApiResponse {
  name: string;
  error: boolean;
}

const jsonText = '{"name":"Bob","error":false}';
const response = JSON.parse(jsonText) as ApiResponse;

console.log(response.name.toUpperCase()); // BOB

This assertion is appropriate when your program generated the JSON itself or another trusted part of your application guarantees the format.

For possibly invalid JSON, use try...catch:

function parseJson(text: string): unknown {
  try {
    return JSON.parse(text);
  } catch {
    return null;
  }
}

const result = parseJson('{"name":"Bob"}');
console.log(result);

Returning unknown is safer than returning any: it requires you to check the value before accessing properties.

Step by Step Execution

Consider this code:

interface Profile {
  name: string;
  error: boolean;
}

const text = '{"name":"Bob","error":false}';
const profile = JSON.parse(text) as Profile;

console.log(profile.name);
console.log(profile.error);

Execution happens in this order:

  1. TypeScript reads the Profile interface. It describes the shape the program expects, but it produces no JavaScript at runtime.

  2. text stores ordinary text. At this point, it is not an object and text.name does not exist.

  3. JSON.parse(text) reads the JSON syntax and creates an object equivalent to:

    { name: "Bob", error: false }
    
  4. as Profile tells the TypeScript type checker to treat that object as a Profile. It does not change the object.

  5. profile.name evaluates to "Bob".

  6. profile.error evaluates to false.

If the text were malformed, such as '{"name":"Bob",}', JSON.parse() would throw a SyntaxError at step 3.

Real World Use Cases

JSON parsing is common whenever an application receives stored or transmitted data as text:

  • HTTP APIs: Parse JSON responses from an API when using a lower-level HTTP client or processing raw response text.
  • Browser storage: Read settings saved with localStorage.setItem().
  • Configuration files: Load JSON configuration for scripts, tools, or servers.
  • Webhooks and message queues: Decode JSON payloads sent by other services.
  • Command-line tools: Read JSON from a file or standard input.

Example: loading saved preferences from browser storage:

interface Preferences {
  theme: "light" | "dark";
  showTips: boolean;
}

const saved = localStorage.getItem("preferences");

if (saved !== null) {
  const preferences = JSON.parse(saved) as Preferences;
  console.log(preferences.theme);
}

Because browser storage can be modified manually or contain old data, production code should validate preferences before using it.

Take Quiz

Real Codebase Usage

In real codebases, developers usually combine parsing with error handling and validation.

Parse only at system boundaries

Keep JSON parsing near the point where text enters the application, such as an HTTP response, file reader, or storage adapter. Convert it to validated application data early.

Use a guard clause for missing input

function loadSettings(text: string | null): unknown {
  if (text === null) {
    return null;
  }

  return JSON.parse(text);
}

Catch invalid JSON

function safeJsonParse(text: string): unknown | null {
  try {
    return JSON.parse(text);
  } catch {
    return null;
  }
}

Validate with a type guard

A type guard checks data at runtime and informs TypeScript about the result.

interface User {
  name: string;
  error: boolean;
}

function isUser(value: unknown): value is User {
  if (typeof value !== "object" || value === null) {
    return false;
  }

  const candidate = value as Record<string, unknown>;

  return (
    typeof candidate.name === "string" &&
    typeof candidate.error === "boolean"
  );
}

const raw: unknown = JSON.parse('{"name":"Bob","error":false}');

if (isUser(raw)) {
  console.log(raw.name.toUpperCase());
} else {
  console.error("The response does not have the expected format.");
}

For large applications, teams may use a schema-validation library to define and validate complex API payloads consistently.

Common Mistakes

Using invalid JSON syntax

JSON is similar to JavaScript object syntax but is stricter. Object keys and string values must use double quotes.

// Invalid JSON: single quotes are not valid in JSON.
const broken = "{'name': 'Bob'}";
JSON.parse(broken); // Throws SyntaxError

Use valid JSON:

const valid = '{"name":"Bob"}';
JSON.parse(valid);

Forgetting that JSON.parse() can throw

Malformed input stops execution unless it is caught.

const data = JSON.parse(userProvidedText); // Can throw SyntaxError

Use try...catch when input may be invalid.

Assuming as SomeType validates data

interface User {
  name: string;
}

const user = JSON.parse('{"id":42}') as User;
console.log(user.name.length); // Runtime error

A type assertion only affects compile-time checking. Validate external input with a type guard or schema.

Treating all parsed values as objects

JSON can contain any JSON value:

JSON.parse('42');          // number
JSON.parse('true');        // boolean
JSON.parse('[1, 2, 3]');   // array
JSON.parse('null');        // null

Check the kind of value you received before accessing object properties.

Parsing an object that is already parsed

const user = { name: "Bob" };
JSON.parse(user); // Type error: JSON.parse expects a string

Only parse strings. Use JSON.stringify() when you need to convert an object into JSON text.

Comparisons

Tool or techniquePurposeImportant detail
JSON.parse(text)Converts JSON text to a JavaScript valueThrows when text is invalid JSON
JSON.stringify(value)Converts a JavaScript value to JSON textOmits some unsupported values, such as functions
as UserTells TypeScript to treat a value as UserDoes not validate runtime data
Type guardChecks a value at runtime and narrows its TypeScript typeUseful after parsing external JSON
unknownRepresents a value whose type is not yet knownMust be checked before use
anyDisables most type checking for a valueConvenient but less safe; JSON.parse() returns this

A useful workflow is:

const raw: unknown = JSON.parse(text);

if (isUser(raw)) {
  // raw is a User here.
}

This is safer than immediately asserting JSON.parse(text) as User when the JSON comes from outside your control.

Take Quiz

Cheat Sheet

// Parse JSON text
const value = JSON.parse('{"name":"Bob"}');

// Describe expected data
interface User {
  name: string;
  error: boolean;
}

// Trusted input only: assertion, not validation
const user = JSON.parse(text) as User;

// Handle malformed JSON
function safeJsonParse(text: string): unknown | null {
  try {
    return JSON.parse(text);
  } catch {
    return null;
  }
}

// Basic runtime object check
function isRecord(value: unknown): value is Record<string, unknown> {
  return typeof value === "object" && value !== null;
}

Rules to remember:

  • TypeScript uses JavaScript's JSON.parse().
  • JSON requires double quotes around keys and string values.
  • JSON.parse() throws SyntaxError for malformed JSON.
  • Parsed JSON may be an object, array, primitive, or null.
  • as Type does not verify the data.
  • Prefer validation for API responses, files, storage, and user input.

FAQ

Does TypeScript have its own JSON parser?

No. TypeScript uses JavaScript's built-in JSON.parse() because TypeScript compiles to JavaScript.

What type does JSON.parse() return in TypeScript?

It returns any. Assigning the result to unknown is often safer when the input is external.

Can I use JSON.parse<MyType>(text) with a generic type?

No. JSON.parse() does not validate or create a value from a generic type. Parse first, then validate or, for trusted data, use an assertion.

Why does JSON.parse() throw an error?

It throws a SyntaxError when the string is not valid JSON, such as when it has trailing commas or uses single quotes.

Is as User safe after parsing JSON?

Only if you fully trust the source and know it always follows the expected format. Otherwise, validate the parsed value first.

Can JSON contain dates?

JSON has no native date type. Dates are normally stored as strings and converted with new Date(value) after validating the string.

How do I parse JSON from localStorage safely?

Check whether getItem() returned null, catch parse errors, and validate the parsed value before using it.

Take Quiz

Mini Project

Description

Build a small parser for saved user preferences. The parser receives JSON text, handles malformed input, and accepts the data only when it matches the expected preference structure. This mirrors how applications safely load browser storage or configuration files.

Goal

Create a function that returns validated preferences or falls back to default preferences.

Requirements

  • Define a Preferences interface with theme and showTips properties.
  • Define default preferences to use when input is missing or invalid.
  • Parse a JSON string without allowing malformed JSON to crash the program.
  • Validate that theme is either "light" or "dark".
  • Validate that showTips is a boolean.
  • Return the default preferences when validation fails.
Take Quiz

Keep learning

Related questions

View more