Warm tip: This article is reproduced from serverfault.com, please click

Importing JSON file in TypeScript

发布于 2018-04-24 08:05:47

I have a JSON file that looks like following:

{

  "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 trying to import it into a .tsx file. For this I added this to the type definition:

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

And I'm importing it like this.

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

And in the file, I use the color primaryMain as colors.primaryMain. However I get an error:

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

Questioner
Sooraj
Viewed
0
Aluan Haddad 2020-03-14 19:01:58

The import form and the module declaration need to agree about the shape of the module, about what it exports.

When you write (a suboptimal practice for importing JSON since TypeScript 2.9 when targeting compatible module formatssee note)

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

You are stating that all modules that have a specifier ending in .json have a single export named default.

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

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

and

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 form is the best and the syntactic sugar it leverages is the very reason JavaScript has default exports.

However I mentioned the other forms to give you a hint about what's going wrong. Pay special attention to the last one. require gives you an object representing the module itself and not its exported bindings.

So why the error? Because you wrote

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

And yet there is no export named primaryMain declared by your "*.json".

All of this assumes that your module loader is providing the JSON as the default export as suggested by your original declaration.

Note: Since TypeScript 2.9, you 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. This is not supported for certain target module formats.