在 TypeScript 中导入 json 文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/49996456/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 19:07:04  来源:igfitidea点击:

Importing json file in TypeScript

jsonangulartypescriptangular8

提问by Sooraj

I have a JSONfile that looks like following:

我有一个JSON如下所示的文件:

{

  "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 .tsxfile. For this I added this to the type definition:

我正在尝试将其导入.tsx文件。为此,我将其添加到类型定义中:

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

And I'm importing it like this.

我是这样导入的。

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

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

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

在文件中,我将颜色primaryMain用作colors.primaryMain. 但是我收到一个错误:

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

属性 'primaryMain' 在类型 'typeof "*.json" 上不存在

采纳答案by Aluan Haddad

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)

当您编写时(从 TypeScript 2.9 开始,在针对兼容的模块格式时导入 JSON 的次优做法,请参阅注释

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

You are stating that all modules that have a specifier ending in .jsonhave a single export nameddefault.

就表示有结尾的符所有模块.json只有一个出口命名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 defaultexports.

第一种形式是最好的,它所利用的语法糖正是 JavaScript 具有default导出功能的原因。

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

但是,我提到了其他形式,以提示您出了什么问题。特别注意最后一个。require为您提供一个表示模块本身而不是其导出绑定的对象。

So why the error? Because you wrote

那么为什么会出错呢?因为你写了

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

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

然而primaryMain,您的"*.json".

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

所有这些都假设您的模块加载器default按照原始声明的建议提供 JSON 作为导出。

Note:Since TypeScript 2.9, you can use the --resolveJsonModulecompiler flagto have TypeScript analyze imported .jsonfiles 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.

注意:从 TypeScript 2.9 开始,您可以使用--resolveJsonModule编译器标志让 TypeScript 分析导入的.json文件并提供有关其形状的正确信息,从而无需通配符模块声明并验证文件是否存在。某些目标模块格式不支持此功能。

回答by kentor

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

使用 TypeScript 2.9.+,您可以简单地导入具有类型安全和智能感知的 JSON 文件,如下所示:

import colorsJson from '../colors.json'; // This import style requires "esModuleInterop", see "side notes"
console.log(colorsJson.primaryBright);

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

确保在compilerOptions您的tsconfig.json文档)部分添加这些设置:

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

Side notes:

旁注:

  • Typescript 2.9.0 has a bug with this JSON feature, it was fixed with 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'
  • Typescript 2.9.0 有一个关于这个 JSON 特性的错误,它在 2.9.2 中被修复
  • esModuleInterop 仅对colorsJson 的默认导入是必需的。如果您将其设置为 false,则必须将其导入import * as colorsJson from '../colors.json'

回答by F?rat Kü?üK

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

使用 typescript 2.9+ 版很容易。因此,您可以轻松地将 JSON 文件导入为@kentor 描述

But if you need to use older versions:

但如果您需要使用旧版本:

You can access JSON files in more TypeScript way. First, make sure your new typings.d.tslocation is the same as with the includeproperty in your tsconfig.jsonfile.

您可以通过更多的 TypeScript 方式访问 JSON 文件。首先,确保您的新typings.d.ts位置与文件中的include属性相同tsconfig.json

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

如果您的tsconfig.json文件中没有包含属性。那么你的文件夹结构应该是这样的:

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

But if you have an includeproperty in your tsconfig.json:

但是,如果你有一个include在你的财产tsconfig.json

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

Then your typings.d.tsshould be in the srcdirectory as described in includeproperty

然后你typings.d.ts应该srcinclude属性中描述的目录中

+ 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.

在许多响应中,您可以为所有 JSON 文件定义全局声明。

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.jsonlike that:

但我更喜欢这种类型的更多版本。例如,假设您有这样的配置文件config.json

{
    "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.jsonconfiguration:

但是在编译阶段,您应该手动将 JSON 文件复制到您的 dist 文件夹中。我只是在我的package.json配置中添加了一个脚本属性:

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

回答by Mehadi Hassan

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

在您的 TS 定义文件中,例如 Typings.d.ts`,您可以添加以下行:

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

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

然后将其添加到您的打字稿(.ts)文件中:-

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

回答by Mr Br

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.

这是您仍然可以定义 json 类型是您想要的并且不必使用通配符。

For example, custom type json.

例如,自定义类型 json。

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

回答by Ruben Palavecino

Often in Node.js applications a .json is needed. With TypeScript 2.9, --resolveJsonModule allows for importing, extracting types from and generating .json files.

通常在 Node.js 应用程序中需要一个 .json。在 TypeScript 2.9 中,--resolveJsonModule 允许从 .json 文件导入、提取类型和生成 .json 文件。

Example #

例子 #

// tsconfig.json

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

// .ts

import settings from "./settings.json";

settings.debug === true;  // OK
settings.dry === 2;  // Error: Operator '===' cannot be applied boolean and number


// settings.json

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