Recently, I was working on a TypeScript project where I needed to import and use data from a JSON file. There are actually several approaches to handling JSON imports in TypeScript, each with its own advantages.
In this tutorial, I’ll guide you through the various methods for importing JSON files in TypeScript, discuss type safety considerations, and demonstrate how to overcome common challenges. So let’s dive in!
Understanding JSON Imports in TypeScript
TypeScript doesn’t natively know how to handle JSON files. By default, when you try to import a JSON file, TypeScript will give you an error like:
Cannot find module './data.json' or its corresponding type declarations.
This is because TypeScript needs to be configured to recognize and handle JSON imports properly. Fortunately, there are several ways to solve this.
Sample JSON File
Throughout this article, I’ll refer to the following sample JSON file (data.json):
{
"users": [
{
"id": 1,
"firstName": "John",
"lastName": "Smith",
"email": "john.smith@example.com",
"isActive": true,
"address": {
"street": "123 Main St",
"city": "Boston",
"state": "MA",
"zipCode": "02108"
},
"tags": ["premium", "verified"]
},
{
"id": 2,
"firstName": "Sarah",
"lastName": "Johnson",
"email": "sarah.j@example.com",
"isActive": false,
"address": {
"street": "456 Oak Ave",
"city": "San Francisco",
"state": "CA",
"zipCode": "94103"
},
"tags": ["trial"]
}
],
"config": {
"apiVersion": "1.0.0",
"environment": "development",
"features": {
"darkMode": true,
"notifications": false
}
}
}
This JSON file contains user data and application configuration that we’ll work with in our examples.
Check out TypeScript Check If String Is Number
Method 1: Enable resolveJsonModule in tsconfig.json
The simplest way to import JSON files in TypeScript is by enabling the resolveJsonModule option in your TypeScript configuration file.
Here are the steps to import JSON files using this method:
- Open your
tsconfig.jsonfile - Add or set
resolveJsonModuletotruein thecompilerOptionssection - Make sure
esModuleInteropis also set totrue
Your tsconfig.json should look something like this:
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"resolveJsonModule": true,
"esModuleInterop": true,
// other options...
}
}
Once you’ve updated your configuration, you can import JSON files directly:
import data from './data.json';
// You can now use the data
console.log(data.firstName); // Assuming data has a firstName property
This approach is clean and straightforward. TypeScript will automatically infer the types from your JSON structure, giving you type checking and autocompletion.
Read Convert TypeScript Enums to Arrays
Method 2: Using require() with Type Assertions
If you’re working in a Node.js environment or can’t modify your tsconfig, you can use the require() function with type assertions:
// Define an interface that matches your JSON structure
interface User {
id: number;
firstName: string;
lastName: string;
email: string;
}
// Use require with type assertion
const userData = require('./user-data.json') as User[];
// Now you can safely use the data with type checking
console.log(userData[0].firstName);
The downside of this approach is that you need to manually define the types that match your JSON structure, which can be tedious for complex JSON files.
Check out How to Use Array.find() in TypeScript?
Method 3: Using the fs Module to Read JSON Files
For more control over when and how the JSON is loaded, you can use the Node.js file system module:
import * as fs from 'fs';
import * as path from 'path';
interface Config {
apiKey: string;
endpoint: string;
timeout: number;
}
function loadConfig(): Config {
const filePath = path.resolve(__dirname, './config.json');
const fileContent = fs.readFileSync(filePath, 'utf-8');
return JSON.parse(fileContent) as Config;
}
const config = loadConfig();
console.log(`API Key: ${config.apiKey}, Endpoint: ${config.endpoint}`);
This approach gives you more flexibility, such as error handling, dynamic file paths, and loading JSON files conditionally.
Check out How to Iterate Over Enums in TypeScript?
Method 4: Using import() with Type Assertions
If you’re using a module bundler like webpack, you can use the dynamic import() function:
interface AppSettings {
theme: string;
notifications: boolean;
language: string;
}
async function loadSettings(): Promise<AppSettings> {
const settings = await import('./settings.json');
return settings.default as AppSettings;
}
// Usage in async context
async function initApp() {
const settings = await loadSettings();
console.log(`Theme: ${settings.theme}, Language: ${settings.language}`);
}
initApp();
This method is useful when you need to load JSON files dynamically based on runtime conditions.
Add Type Definitions for JSON Files
For better type safety, you can create type definitions for your JSON files. Here’s how:
- Create a
types.d.tsfile in your project - Add module declarations for your JSON files
// types.d.ts
declare module "*.json" {
const value: any;
export default value;
}
For more specific typing, you can declare types for individual files:
// types.d.ts
declare module "./user-data.json" {
export interface User {
id: number;
firstName: string;
lastName: string;
email: string;
}
const value: User[];
export default value;
}
Working with Dynamic JSON Properties
Sometimes, your JSON might have dynamic keys or complex structures. Here’s how to handle them:
// For a JSON with dynamic keys
interface DynamicData {
[key: string]: {
value: number;
label: string;
}
}
import stateData from './us-states.json';
// Using the data
const californiaInfo = (stateData as DynamicData)['California'];
console.log(`${californiaInfo.label}: ${californiaInfo.value}`);
Check out TypeScript Promise
Real-World Example: Working with US State Data
Let’s look at a practical example using US state data:
// us-states.json
{
"AL": {
"name": "Alabama",
"capital": "Montgomery",
"population": 4903185
},
"AK": {
"name": "Alaska",
"capital": "Juneau",
"population": 731545
},
// ...other states
}
Now let’s import and use this data:
// Enable resolveJsonModule in tsconfig.json first
// Define the types
interface StateInfo {
name: string;
capital: string;
population: number;
}
interface States {
[stateCode: string]: StateInfo;
}
// Import the JSON
import statesData from './us-states.json';
// Type assertion
const states = statesData as States;
// Use the data
function getStateCapital(stateCode: string): string | undefined {
return states[stateCode]?.capital;
}
function getPopulationByState(stateName: string): number | undefined {
const stateEntry = Object.entries(states).find(
([_, info]) => info.name === stateName
);
return stateEntry?.[1].population;
}
// Example usage
console.log(`The capital of California is ${getStateCapital('CA')}`);
console.log(`Florida has a population of ${getPopulationByState('Florida')}`);
Troubleshooting Common Issues
Here are some common issues that you might face and fixes.
Issue 1: Module not found errors
If you’re still getting “Cannot find module” errors despite enabling resolveJsonModule, try these fixes:
- Make sure your TypeScript version is 2.9.0 or higher
- Verify that both
resolveJsonModuleandesModuleInteropare set totrue - Check the file path is correct (case-sensitive!)
- Restart your TypeScript server (in VS Code: Ctrl+Shift+P → “TypeScript: Restart TS Server”)
Issue 2: Type errors when accessing properties
If TypeScript doesn’t recognize properties in your JSON:
// Add a type assertion when importing
import rawData from './data.json';
interface MyData {
user: {
name: string;
age: number;
}
}
const data = rawData as MyData;
console.log(data.user.name); // Now TypeScript knows this exists
In this tutorial, I explained how to import JSON files in TypeScript using different methods. I hope you found this article helpful.
You may also like:

Hey! I’m Bijay Kumar, founder of SPGuides.com and a Microsoft Business Applications MVP (Power Automate, Power Apps). I launched this site in 2020 because I truly enjoy working with SharePoint, Power Platform, and SharePoint Framework (SPFx), and wanted to share that passion through step-by-step tutorials, guides, and training videos. My mission is to help you learn these technologies so you can utilize SharePoint, enhance productivity, and potentially build business solutions along the way.