Importing JSON in TypeScript: A Complete Guide with Examples

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

How to Import JSON in TypeScript Without Losing Your Mind

\n\n

If you've ever tried to do import data from './config.json' in TypeScript, you know that feeling: the compiler turns red, complains, and throws an error Cannot find module. Sound familiar? You bet! The question about importing JSON in TypeScript is one of the most popular on Stack Overflow. And it's no wonder: JSON is used everywhere — configs, localization, mock data, static lists. But TypeScript doesn't know how to work with JSON files by default.

\n\n

In this tutorial, we'll cover all the ways to import JSON in TypeScript — from simply enabling a flag in tsconfig to advanced typing. You'll learn how to make TypeScript play nice with JSON, and you'll never see that red error again. Let's go!

\n\n

Why Doesn't TypeScript See JSON?

\n

Before diving into the code, let's understand the reason. TypeScript is a superset of JavaScript that adds static typing. By default, the TypeScript compiler expects all imported modules to be .ts or .js files. JSON is not a module; it's a data format. TypeScript simply doesn't know how to interpret it.

\n

The solution lies in two areas:

\n
    \n
  • Compiler configuration — enable JSON support via the resolveJsonModule flag.
  • \n
  • Module declaration — manually describe the type for JSON files if the flag isn't suitable.
  • \n
\n\n

Method 1: Enable resolveJsonModule (The Right Way)

\n

The simplest and recommended way is to add the resolveJsonModule option to tsconfig.json. This flag tells TypeScript: "Hey buddy, let's import JSON like regular modules."

\n
// tsconfig.json\n{\n    "compilerOptions": {\n        "resolveJsonModule": true,\n        "esModuleInterop": true\n    }\n}
\n

After that, you can safely write:

\n
// config.ts\nimport config from './config.json';\n\nconsole.log(config.apiUrl); // works!\nconsole.log(config.port);    // works!
\n

What's happening here? TypeScript automatically creates types for the imported JSON. If your JSON has a field apiUrl: string and port: number, TypeScript will infer their types and check their usage. Cool, right?

\n

But there's a catch: resolveJsonModule also requires enabling esModuleInterop or allowSyntheticDefaultImports for the default import to work correctly. Without this, you'll get an error when trying to import.

\n\n

Method 2: Import with Named Exports

\n

Sometimes you don't need the entire JSON, only specific fields. TypeScript supports this too:

\n
import { apiUrl, port } from './config.json';\n\nconsole.log(apiUrl); // string\nconsole.log(port);   // number
\n

This is possible thanks to so-called "tree-shaking" in bundlers (Webpack, Vite), but at the TypeScript level, it's just object destructuring. However, remember: if you use resolveJsonModule, TypeScript automatically creates types for all fields, so you can safely import either the entire object or its parts.

\n\n

Method 3: require Instead of import (For Older Projects)

\n

If you're working on a project where resolveJsonModule cannot be enabled for some reason (e.g., conflict with other settings), you can use the good old require:

\n
const config = require('./config.json');\n\nconsole.log(config.apiUrl); // works, but without types
\n

The problem with this approach is obvious: you lose typing. TypeScript doesn't know what's inside config and will treat it as type any. This opens the door to errors. If you must use require, at least add a type declaration:

\n
interface Config {\n    apiUrl: string;\n    port: number;                

Blogs

Book Recommendations