Importing json file in TypeScript

佐手、 提交于 2019-11-26 04:13:08

问题


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\"


回答1:


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

When you write (a bad practice for JSON files 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 which is of type any.

There are several ways you can 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.




回答2:


With TypeScript 2.9.+ you can simply import JSON files with typesafety and intellisense like this:

import colorsJson from '../colors.json';
console.log(colorsJson.primaryBright);

Make sure to add these settings in the compilerOptions section of your tsconfig.json (documentation):

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

Side notes:

  • Typescript 2.9.0 has a bug with this JSON feature, I believe it got fixed with 2.9.1 or 2.9.2
  • The esModuleInterop is only necessary for the default import of the colorsJson. If you leave it set to false then you have to import it with import * as colorsJson from '../colors.json'



回答3:


It's easy to use typescript version 2.9+. So you can easily import JSON files as @kentor decribed.

But if you need to use older versions:

You can access JSON files in more TypeScript way. First, make sure your new typings.d.ts location is the same as with the include property in your tsconfig.json file.

If you don't have an include property in your tsconfig.json file. Then your folder structure should be like that:

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

But if you have an include property in your tsconfig.json:

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

Then your typings.d.ts should be in the src directory as described in include property

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

As In many of the response, You can define a global declaration for all your JSON files.

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

but I prefer a more typed version of this. For instance, let's say you have configuration file config.json like that:

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

Then we can declare a specific type for it:

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

It's easy to import in your typescript files:

import * as Config from 'config.json';

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

But in compilation phase, you should copy JSON files to your dist folder manually. I just add a script property to my package.json configuration:

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



回答4:


In your TS Definition file, e.g. typings.d.ts`, you can add this line:

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

Then add this in your typescript(.ts) file:-

import * as data from './colors.json';
const word = (<any>data).name;



回答5:


Another way to go

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

This was you still can define json type is you want and don't have to use wildcard.

For example, custom type json.

interface User {
  firstName: string;
  lastName: string;
  birthday: Date;
}
const user: User = require('./user.json');



回答6:


First, you have to allow to import json file as a module. To do that, add "resolveJsonModule": true to your tsconfig.json file, in the compilerOptions part:

{
  // ...
  "compilerOptions": {
    // ...
    "resolveJsonModule": true
  },
  // ...
}

Then, you can import the json like that:

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

After that, you can simply use the colors object



来源:https://stackoverflow.com/questions/49996456/importing-json-file-in-typescript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!