在TypeScript中导入JSON文件

我有一个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"
}

我试图将它导入.tsx文件。为此,我在类型定义中添加了如下内容:

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

我像这样导入它。

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

在文件中,我使用颜色primaryMain作为colors.primaryMain。但是我得到一个错误:

属性“primaryMain”在类型“*.json”中不存在

501669 次浏览

导入表单和模块声明需要就模块的形状以及它导出的内容达成一致。

当你编写(导入JSON的次优做法,因为TypeScript 2.9当目标是兼容的模块格式__abc0)

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

你是在声明所有以.json结尾的说明符的模块都有一个导出命名 default

有几种方法可以正确地使用这样的模块,包括

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

而且

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

而且

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

而且

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

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

不过,我提到了其他表单,以提示您哪里出了问题。特别注意最后一个。require提供了一个表示模块本身的对象,提供了它导出的绑定。

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

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

但是你的"*.json"没有声明名为primaryMain的导出。

所有这些都假设你的模块加载器提供JSON作为default导出,正如你最初的声明所建议的那样。

注意:从TypeScript 2.9开始,你可以使用--resolveJsonModule编译器标志让TypeScript分析导入的.json文件,并提供关于其形状的正确信息,从而避免了通配符模块声明和验证文件的存在。某些目标模块格式不支持这一点。

使用TypeScript 2.9。+你可以简单地导入JSON文件,这样做有类型安全和智能感知的好处:

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

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

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

边注:

  • Typescript 2.9.0在这个JSON特性上有一个bug,它在2.9.2被修复了
  • esModuleInterop只对colorsJson的默认导入是必需的。如果你让它设置为false,那么你必须用import * as colorsJson from '../colors.json'导入它

使用typescript 2.9+版本很容易。因此,您可以轻松地导入JSON文件作为@kentor延伸

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

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

如果你的tsconfig.json文件中没有include属性。然后你的文件夹结构应该是这样的:

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

但是如果你在你的tsconfig.json中有一个include属性:

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

然后你的typings.d.ts应该在src目录中,如include属性所述

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

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

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

但我更喜欢打字的版本。例如,假设你有这样的配置文件config.json:

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

然后我们可以为它声明一个特定的类型:

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

它很容易在你的typescript文件中导入:

import * as Config from 'config.json';


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

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

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

另一种方法

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

你仍然可以定义json类型,不需要使用通配符。

例如,自定义类型json。

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

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

例#

// 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.html < / p >

tsconfig.json文件中启用"resolveJsonModule": true并实现如下代码,这对我来说是工作:

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

你应该加上

"resolveJsonModule": true

作为tsconfig.json的compilerOptions的一部分。

下面是如何在运行时导入json文件

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

这样就避免了在导入大文件时tsc变慢或内存不足的问题,这些问题都可能发生在使用resolveJsonModule时。

注意,如果你使用@kentor方式

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

你需要在tsc命令后面添加--resolveJsonModule和__abc1来编译TypeScript文件。

< p >的例子: tsc --resolveJsonModule --esModuleInterop main.ts < / p >

在我的情况下,我不得不改变:"include": ["src"]"include": ["."],除了"resolveJsonModule":true,因为我试图从项目的根导入manifest.json,而不是从./src

在Angular (typescript)应用中,我需要在我的environment.ts中包含一个.json文件。要做到这一点,我必须在tsconfig中设置两个选项:

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

然后,我可以将json文件导入environment.ts:

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

在我的例子中,我需要改变tsconfig.node.json:

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

像这样导入:

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

或者像这样:

import colors from './colors.json'

“esModuleInterop":没错