Utilizing JSON Files in TypeScript

I have a JSON file with color values that are structured like so:

{
  "primaryBright":    "#2DC6FB",
  "primaryMain":      "#05B4F0",
  "primaryDarker":    "#04A1D7",
  "primaryDarkest":   "#048FBE",

  "secondaryBright":  "#4CD2C0",
  "secondaryMain":    "#00BFA5",
  "secondaryDarker":  "#009884",
  "secondaryDarkest": "#007F6E",

  "tertiaryMain":     "#FA555A",
  "tertiaryDarker":   "#F93C42",
  "tertiaryDarkest":  "#F9232A",

  "darkGrey":         "#333333",
  "lightGrey":        "#777777"
}

I'm attempting to bring this data into a .tsx file. To do this, I updated the type definition as follows:

declare module "*.json" {
  const value: any;
  export default value;
}

The import statement in my file looks like this:

import colors = require('../colors.json')

To use the color primaryMain, I reference it as colors.primaryMain. However, I encounter an error message:

Property 'primaryMain' does not exist on type 'typeof "*.json"

Answer №1

Utilizing TypeScript version 2.9.+ provides the ability to effortlessly import JSON files, offering advantages such as type safety and intellisense with this approach:

import colorsJson from '../colors.json'; // To use this import style, ensure "esModuleInterop" is enabled (refer to "side notes")
console.log(colorsJson.primaryBright);

Don't forget to include these configurations in the compilerOptions section of your tsconfig.json file (documentation):

"resolveJsonModule": true,
"esModuleInterop": true,

Additional Information:

  • It's worth noting that TypeScript 2.9.0 had a bug related to this JSON feature, which was rectified in version 2.9.2
  • The esModuleInterop setting is specifically required for default importing colorsJson. If set to false, an alternative import method would be using
    import * as colorsJson from '../colors.json'

Answer №2

It is essential for the import form and module declaration to be in sync regarding the structure of the module and its exports.

When utilizing (not the recommended method for importing JSON since TypeScript 2.9 when targeting compatible module formatsrefer to note)

declare module "*.json" {
  const value: any;
  export default value;
}

This indicates that modules with a specifier ending in .json have a single export by the name of default.

There are various correct ways to consume such a module, including

import a from "a.json";
a.primaryMain

as well as

import * as a from "a.json";
a.default.primaryMain

and

import {default as a} from "a.json";
a.primaryMain

and

import a = require("a.json");
a.default.primaryMain

The first approach is preferred, leveraging JavaScript's use of default exports.

I mentioned the alternative forms to provide insight into potential issues. Pay close attention to the last one. require returns the module object itself, not its exported bindings.

So why the error? Because you wrote

import a = require("a.json");
a.primaryMain

However, there is no export named primaryMain declared in your "*.json" file.

All this assumes that your module loader is indeed offering the JSON as the default export as per your original statement.

Note: With TypeScript 2.9, you can utilize the --resolveJsonModule compiler flag to analyze imported .json files accurately, eliminating the need for a wildcard module declaration and ensuring file presence validation. Note that this feature may not apply to certain target module formats.

Answer №3

Learn how to dynamically load a JSON file in your code

import fs from 'fs'
var dataArray = JSON.parse(fs.readFileSync('data.json', 'utf-8'))

By following this method, you can prevent potential issues with typescript compiler slowing down or crashing due to importing large files, a common occurrence when using resolveJsonModule.

Answer №4

For my specific scenario, I found it necessary to make alterations to tsconfig.node.json:

{
  "compilerOptions": {
    ...
    "resolveJsonModule": true
  },
  "include": [..., "colors.json"]
}

To perform the import in this manner:

import * as colors from './colors.json'

Alternatively, like so:

import colors from './colors.json'

when using "esModuleInterop": true

Answer №5

Utilizing TypeScript version 2.9 and above makes importing JSON files a seamless process, as pointed out by @kentor.

However, for those working with older versions:

To access JSON files in a more TypeScript-friendly manner, ensure that the location of your new typings.d.ts file matches the include property specified in your tsconfig.json file.

If the tsconfig.json file does not include an include property, then the folder structure should resemble this:

- app.ts
+ node_modules/
- package.json
- tsconfig.json
- typings.d.ts

On the other hand, if there is an include property in your tsconfig.json:

{
    "compilerOptions": {
    },
    "exclude"        : [
        "node_modules",
        "**/*spec.ts"
    ], 
    "include"        : [
        "src/**/*"
    ]
}

In this case, the typings.d.ts file should reside within the src directory as per the include property.

+ node_modules/
- package.json
- tsconfig.json
- src/
    - app.ts
    - typings.d.ts

Many responses suggest defining a global declaration for all JSON files.

declare module '*.json' {
    const value: any;
    export default value;
}

For a more specific approach, consider creating custom typings for individual JSON files. For example, suppose you have a configuration file named config.json structured like this:

{
    "address": "127.0.0.1",
    "port"   : 8080
}

You can define a type specifically for this file:

declare module 'config.json' {
    export const address: string;
    export const port: number;
}

Importing these typed JSON files into your TypeScript code is straightforward:

import * as Config from 'config.json';

export class SomeClass {
    public someMethod: void {
        console.log(Config.address);
        console.log(Config.port);
    }
}

During compilation, remember to manually copy JSON files to your distribution folder. One way to do this is by adding a script to your package.json:

{
    "name"   : "some project",
    "scripts": {
        "build": "rm -rf dist && tsc && cp src/config.json dist/"
    }
}

Answer №6

When working on an Angular project using typescript, I encountered the need to include a .json file in my environment.ts file. In order to achieve this, I had to configure two options in tsconfig:

{
  "compilerOptions": {
    "moduleResolution": "node",
    "resolveJsonModule": true
  }
}

After setting up the tsconfig, I was able to import the json file into my environment.ts like so:

import { default as someObjectName } from "../some-json-file.json";

Answer №7

For proper setup,

"resolveJsonModule": true

must be included within compilerOptions in tsconfig.json file.

Answer №8

To import a JSON file without making changes to tsconfig, you can specify that you are importing JSON explicitly.

import dataFile from './dataFile.json' assert { format: "json" };

While this may not completely address the issue at hand, it is a common query among individuals seeking guidance on how to load JSON directly from a file.

Answer №9

Node.js applications often require the use of .json files. Thanks to TypeScript 2.9, the --resolveJsonModule flag allows for easy importing, extracting types from, and generating .json files.

Check out this example:

// tsconfig.json

{
    "compilerOptions": {
        "module": "commonjs",
        "resolveJsonModule": true,
        "esModuleInterop": true
    }
}

// .ts

import settings from "./settings.json";

settings.debug === true;  // This is valid
settings.dry === 2;  // This will throw an error: Operator '===' cannot be applied to types boolean and number


// settings.json

{
    "repo": "TypeScript",
    "dry": false,
    "debug": false
}
by: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-9.html

Answer №10

Exploring another approach

const info: {[key: string]: any} = require('./info.json');

This way, you can specify the JSON type without resorting to a wildcard.

For instance, creating a customized JSON type.

interface Person {
  name: string;
  age: number;
  birthDate: Date;
}
const personInfo: Person = require('./person.json');

Answer №11

TypeScript 5.3 brought forth the concept of Import Attributes, previously known as Import Assertions, allowing for defining the expected format of imported modules at runtime.

By utilizing Import Attributes, it ensures that modules are imported in the correct format, ensuring that a file with a .json extension actually contains executable JavaScript code and is appropriately interpreted as JSON.

import colors from "./colors.json" with { type: "json" };

Answer №12

To activate the feature, set

"resolveJsonModule": true
in your tsconfig.json configuration file and use the following code implementation:

const settings = require('./settings.json');

Answer №13

Keep in mind that if you follow the strategies outlined by @kentor

Ensure to include these configurations in the compilerOptions section of your tsconfig.json (reference):

You must append --resolveJsonModule and --esModuleInterop after the tsc command to compile your TypeScript file.

For instance:

tsc --resolveJsonModule --esModuleInterop main.ts

Answer №14

My scenario required me to make a modification:

"include": ["src"]
had to be changed to
"include": ["."]
. This change was necessary alongside setting
"resolveJsonModule":true
as I was attempting to import manifest.json from the project's root directory instead of ./src.

Answer №15

Using the require method is a commonly utilized technique for loading JSON files within Node.js

Answer №16

I have tested all the recommendations provided in this discussion so far, such as enabling resolveJsonModule, setting moduleResolution to "node", and trying different formats of the include statement (assert/with) and require. Despite closing and reopening VSCode multiple times after each change, none of these approaches proved effective.

However, I managed to make

import metadata from './block.json
work without any errors by adjusting the tsconfig.json settings. By specifying "include": ["src"] and adding "files":["src/block.json"], the JSON file was successfully imported even though it was not located in the rootDir.

Interestingly, even when 'metadata' showed errors for './block.json', Intellisense displayed all the defined properties from the JSON file. This project does not contain a declaration for the schema, but VSCode still recognized the file contents despite TypeScript indicating an error.

It's worth noting that I cannot confirm if this solution is version-specific. In my setup, I am using TypeScript 5.3.3, @types/node 20.11.24, along with the provided tsconfig.json configuration. The source files in the src folder are processed by WebPack into ./build. (Note: Mentions of ./dist are included in case TypeScript requires a different outDir compared to WebPack.)

This may not be the definitive solution for everyone, and there could be more elegant alternatives depending on specific needs. However, for me at this moment, this configuration serves as a working solution.

{
    "compilerOptions": {
        // Compiler options here
    },
    "include": ["src"],
    "files": ["src/block.json"]
}

Answer №17

bring in information from '../../data/data.json;

can be a viable choice as well.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Encountering a problematic JQuery Ajax request to a RESTful API

I am currently in the process of trying to authenticate against demo webservices that were developed by one of my colleagues. While Cross-origin resource sharing is allowed and functions perfectly when I attempt to call from the Advanced Rest Client plugin ...

Is it possible to utilize a function to manipulate the [checked] attribute of a checkbox and toggle it between true and false?

I'm trying to update the checkbox's [checked] property by calling a method, but even though the method is being called, the checkbox status doesn't change. HTML <div*ngFor="let vest_style of VEST_STYLE"> <input type="checkbox" ...

Encounter difficulties with KeyConditionExpression when querying a DynamoDB table

How can I resolve the error below and what is causing "operand type: M" to appear? Despite consulting AWS documentation and searching on stack overflow, I have been unable to find a solution to this issue after spending several hours. My goal is to query a ...

Import JSON data into Angular 2 Component

After much effort, I have finally figured out how to load JSON data into an Angular 2 Component. datoer.service.ts: import { Injectable } from '@angular/core'; import { Http, Response } from '@angular/http'; import { Observable } from ...

The sequence of initializing test hooks in inconsistent playwright tests

My testing framework setup looks something like this: test.describe("...", () => { let p: Page; test.beforeEach(async({browser}) => { p = await (await browser.newContext()).newPage(); } test(...); test(...); test.aft ...

Suggestions for importing by Typescript/VS Code

Imagine you have a file called a.ts that contains 4 named imports: export const one = 1 export const two = 2 export const three = 3 export const four = 4 Next, you have a file named b.ts and you want to import some variables from a.ts. import {} from &a ...

how to use JSON to communicate between AngularJS controller and PHP

I am facing an issue with sending multiple data from JavaScript to PHP using AngularJS. Despite my efforts, I am unable to receive any data. As a beginner in AngularJS, I have included the following JS code: var data = {"name":name, "cin":cin, "job":job}; ...

Try utilizing varied coding keys when you're encoding or decoding data in Swift

I need to extract information from the JSON object below: { "id": "..." "someData": { ... }, "elements": { "values": [ { "id": "1", ... }, { ...

Monitor the closure of a programmatically opened tab by the user

Currently, I am in the process of developing a web application using Angular 11 that interacts with the msgraph API to facilitate file uploads to either onedrive or sharepoint, and subsequently opens the uploaded file in the Office online editor. Although ...

Guide on iteratively creating and appending data to a JSON file

My testing scenario involves calling the addEachEmployeeDetailsToJSONFile method multiple times with different employee details each time. The desired outcome is to generate a JSON file named mapping.json structured as follows: EXPECTED mapping.json Stru ...

Developing with Cordova involves collaborating with PHP and MySQL for efficient and seamless

As a newcomer to the world of cordova, I am currently in the process of familiarizing myself with its syntax. At this stage, I have manually inputted some json data and developed an application. In this app, when a user chooses a serial number from a dropd ...

Error message: Django encountered an issue with the serializer stating that a 'NoneType' object does not have the attribute '_meta'

Recently, I came across a useful piece of code for JSON serializing different objects in Django. However, the code is throwing an AttributeError when it encounters certain types of models. Below is the error message and traceback that I'm currently t ...

"Encountering issue with React as old state is being sent instead of updated state when invoking

I am encountering an issue with state variables in my react + mobx + MaterialUI frontend. I have a button that should trigger a function to convert certain state variables into an object and send it to another object for further processing. Strangely, when ...

Decoding JSON data into a multidimensional array

Upon receiving data from an API, the following information is retrieved: { "isVacation":"1", "date":"25.12.2014", "occasion":"1. Christmas Day", "locations":["BW","BY","BE","BB","HB","HH","HE","MV","NI","NW","RP","SL","SN","ST","SH","T ...

How can I generate codegen types using typeDefs?

I have been exploring the capabilities of graphql-codegen to automatically generate TypeScript types from my GraphQL type definitions. However, I encountered an issue where I received the following error message: Failed to load schema from code file " ...

Prohibit communication by any means

Let's take a look at the following function overloads: function f(key: undefined); function f(key: string | undefined, value: object | undefined); I want to allow calls with a single explicit undefined argument f(undefined), but require two argument ...

Serializing MongoDb .NET ObjectIds

Recently, while working with my .NET 6.0 API, I encountered a situation involving a particular model: public class Tournament { public List<ObjectId> FriendsId { get; set; } After serialization, the model looks like this: {"FriendsId" ...

Encountering an "unexpected token" error while utilizing the JSOP API in a ReactJS application

I am facing an issue while fetching data from a JSON API, as it is throwing an "Unexpected token" error. Below is the code that I have tried so far. Any help in resolving this problem would be greatly appreciated. Below is the code snippet: var Demo = Re ...

CompositeAPI: Referencing HTML Object Template - Error TS2339 and TS2533 when using .value to access Proxy Object

Having trouble referencing an element in VueJS 3 CompositeAPI. In my current implementation, it looks like this: <div ref="myIdentifier"></div> setup() { const myIdentifier = ref(null); onMounted(() => { console.log(myIden ...

Tips for aligning the output of a Google Translate search with the original input string

I need to translate a large number of US English strings into various other languages. I have a JSON string with the following format: "AdminLocales": { "-locale": "en_US", "global": { "search": "Search", "noOrdersFound": "No Orders Fo ...