TypeScript 2.9 introduced a new --resolveJsonModule compiler option that lets us import JSON modules from within TypeScript modules.

#Importing JSON Modules via require Calls

Let’s assume we have a Node application written in TypeScript, and let’s say that we want to import the following JSON file:

{
  "server": {
    "nodePort": 8080
  }
}

In Node, we can use a require call to import this JSON file like any other CommonJS module:

const config = require("./config.json");

The JSON is automatically deserialized into a plain JavaScript object. This allows us to easily access the properties of our config object:

"use strict";

const express = require("express");
const config = require("./config.json");

const app = express();

app.listen(config.server.nodePort, () => {
  console.log(`Listening on port ${config.server.nodePort} ...`);
});

So far, so good!

# Importing JSON Files via Static import Declarations

Let’s now say we want to use native ECMAScript modules instead of CommonJS modules. This means we’ll have to convert our require calls to static import declarations:

// We no longer need the "use strict" directive since
// all ECMAScript modules implicitly use strict mode.

import * as express from "express";
import * as config from "./config.json";

const app = express();

app.listen(config.server.nodePort, () => {
  console.log(`Listening on port ${config.server.nodePort} ...`);
});

Now, we get a type error in line 2. TypeScript doesn’t let us import a JSON module out of the box, just like that.

Let’s head over to our tsconfig.json file and enable the resolveJsonModule option there:

{
  "compilerOptions": {
    "target": "es2015",
    "module": "commonjs",
    "strict": true,
    "moduleResolution": "node",
    "resolveJsonModule": true
  }
}

With --resolveJsonModule enabled, we no longer get a type error in our TypeScript file. Even better, we now get type checking and autocompletion!

And there you go! This is how to import JSON modules from within TypeScript modules, only one compiler option away.

Definition type File.

Since TypeScript 2.9, we can use the --resolveJsonModule compiler flag to have TypeScript analyze imported .json files and provide correct information regarding their shape obviating the need for a wildcard module declaration and validating the presence of the file.

However, sometimes, for different reasons it might be, we still need to define the format of our Objet. And for that, we can do it in 2 differents ways :

1 -Use of “esModuleInterop” compiler fla

{
  "compilerOptions": {
    "target": "es2015",
    "module": "commonjs",
    "strict": true,
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "esModuleInterop": true,
  }
}

2 – Adding extra @Type definitions (typing.d.ts), as followed:

let´s create a typing.d.ts file, and define the declarations module, for all JSON files.

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

That way, we are stating that all modules that have a specifier ending in .json have a single export named default.

How to use our Object JSON in the application ?

Example:

Let´s say we have a JSON file that looks like following:

{
 "primaryBright":    "#2DC6FB",
  "primaryMain":      "#05B4F0",
  "darkGrey":         "#333333",
  "lightGrey":        "#777777"
}

There are several ways you can correctly consume such a module including

import a from "a.json";

//then in the code, you can use it that way:
a.primaryMain

and

import * as a from "a.json";

//then in the code, you can use it that way:
a.default.primaryMain

and

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

//then in the code, you can use it that way:
a.primaryMain

and

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

//then in the code, you can use it that way:
a.default.primaryMain

# Using Dynamic Imports:

Some time, we might need to import the file dynamically.

For e.g. based on some condition, import file 1

if (condition){
    // import file1;
 }

And that´s how, we will make the import: ( see code below)

const data_json = import("../app_data_files/file1.json");

Note: Dynamic Import will return a promise. you can either use async/await or .then to get the json objects

By Shabazz

Software Engineer, MCSD, Web developer & Angular specialist

Leave a Reply

Your email address will not be published. Required fields are marked *