如何将 JSON 文件导入 TypeScript 文件?

140

我正在使用Angular Maps构建一个地图应用程序,并希望将JSON文件导入为定义位置的标记列表。我希望在app.component.ts中使用这个JSON文件作为marker[]数组,而不是在TypeScript文件中定义硬编码的marker数组。

请问最佳的导入JSON文件并在项目中使用的过程是什么?非常感谢您的指导!


你可以看到我的答案适用于 Angular 7+。 - Yulian
12个回答

211

在最近一次 TypeScript 更新之前,Aonepathan 的单行代码对我起作用。

我发现 Jecelyn Yeen 的文章,建议将以下片段发布到您的 TS 定义文件中

在项目的根文件夹中添加名为typings.d.ts的文件,并加入以下内容。

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

然后像这样导入您的数据:

import * as data from './example.json';

2019年7月更新:

Typescript 2.9(文档)引入了一种更好、更智能的解决方案。步骤如下:

  1. 在您的 tsconfig.json 文件中添加以下行以支持 resolveJsonModule
"compilerOptions": {
    ...
    "resolveJsonModule": true
  }

现在,import语句可以默认导入:

import data from './example.json';

Intellisense现在会检查JSON文件,以确定您是否可以使用Array等方法。非常酷。


3
我也试过这个方法,非常有效!注意:为了正确编译,你需要重新启动开发服务器。 - Scott Byers
17
我收到了您的翻译请求。原文中提到了一个错误信息,大意是无法找到以.json结尾的模块,建议使用--resolveJsonModule选项来导入该模块。 - Jeremy Thille
9
根据 TypeScript 文档的要求,我需要添加 "esModuleInterop": true,。但是他们也建议将 module 设置为 commonjs 而不是 esnext,虽然两者似乎都起作用。请问是否有理由切换到 commonjs(文档中提到)而不是保持默认的 esnext - timhc22
10
在一个新的Angular 9.1.11项目中,我不得不在compilerOptions中添加"allowSyntheticDefaultImports": true - yohosuff
2
这个更改破坏了 import * as moment from 'moment' 语句。将其更改为 import moment from 'moment' 可以解决问题。此外,需要重新启动 VS Code。 - matrix
显示剩余9条评论

68

这篇Reddit帖子所述,在Angular 7之后,您可以将事情简化为以下两个步骤:

  1. 在您的tsconfig.json文件中的compilerOptions中添加这三行:
"resolveJsonModule": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true

导入您的 JSON 数据:
import myData from '../assets/data/my-data.json';

就是这样了。现在你可以在组件/服务中使用myData了。


1
esModuleInterop 是用来做什么的? - giovannipds
@giovannipds 这是用于默认的 JSON 导入。 - Vasia Zaretskyi
在我的情况下,Angular 10和Typescript 4.0.2,我不需要使用“allowSyntheticDefaultImports”。 - MarshHawk
只有这个解决方案对我起作用 :) - WISERDIVISOR

31

感谢大家的建议,我已经找到解决方法了。我在app.component.ts文件的顶部添加并定义了json:

var json = require('./[yourFileNameHere].json');

最终产生了标记,这是一行简单的代码。


7
我遇到了 error TS2304: Cannot find name 'require'. 的问题。根据 https://dev59.com/HVgQ5IYBdhLWcg3wORZJ#43122829 中已接受答案的评论,通过添加 declare var require: any; 解决了该问题。 - Ben
4
@Ben,你需要在你的tsconfig里加入node类型。例如:"compilerOptions": { ... "types": ["node"] }, 对于需要该信息的人,以下是相关答案链接:https://dev59.com/-10Z5IYBdhLWcg3wrR8r#35961176 - Kody
嗨@aonepathan,希望你能帮我:我有一个库,使用require读取json文件。 var json = require('./[yourFileNameHere]');没有扩展名。在编译时,我遇到了一个错误:Module not found: Error: Can't resolve [yourFileNameHere] in [file name]你有什么办法来解决这个问题吗? - Neo1975

26

以下是基于@ryanrain答案的Angular 6+完整答案:

angular-cli文档中可以得知,json文件可以被视为assets并且可以通过标准导入方式访问,而无需使用ajax请求。

假设您将json文件添加到“your-json-dir”目录中:

  1. 将“your-json-dir”添加到angular.json文件中:

    "assets": [ "src/assets", "src/your-json-dir" ]

  2. 创建或编辑typings.d.ts文件(位于项目根目录),并添加以下内容:

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

    这将允许导入“.json”模块而不会出现TypeScript错误。

  3. 在您的控制器/服务/任何其他文件中,只需使用相对路径导入文件即可:

    import * as myJson from 'your-json-dir/your-json-file.json';


3
如果我没有 typings.d.ts 文件怎么办? - Kristopher Windsor
2
然后您需要在项目根目录下创建一个文件,其中只包含步骤2的内容。 - Benjamin Caure
2
重要提示:将自定义类型文件添加到tsconfig.json中的typeRoots中 "typeRoots": ["node_modules/@types", "src/typings.d.ts"], - Japo Domingo

18

第一种解决方案 - 只需将您的 .json 文件扩展名更改为 .ts,并在文件开头添加 export default ,如下所示:

export default {
   property: value;
}

那么您只需简单地导入文件,无需添加类型,就像这样:

import data from 'data';

第二种解决方案是通过 HttpClient 获取 JSON。

将 HttpClient 注入到组件中,像这样:

export class AppComponent  {
  constructor(public http: HttpClient) {}
}

然后使用这段代码:

this.http.get('/your.json').subscribe(data => {
  this.results = data;
});

https://angular.io/guide/http

与这里提供的其他解决方案相比,此解决方案有一个明显的优势 - 如果您的json更改(它是从单独的文件动态加载的,因此只需修改该文件即可),它不需要您重新构建整个应用程序。


2
如果您的数据是静态的并且将长时间不变,那么第一种解决方案是不错的选择;它可以帮助您节省不必要的 HTTP 请求。但是,如果这些数据经常发生变化,那么请使用服务器发送的第二种解决方案,或者甚至考虑将其添加到数据库中(如果数据集非常庞大)。 - OzzyTheGiant

15

1
这对我来说是最好的解决方案。不需要 typings 文件,而且 TS 可以为您解析属性名称。 - Steve Hobbs
1
这是一个很好的解决方案,你甚至不需要使用JSON.parse()。它是一个常见的TS对象,直接可以使用! - Brendan Sluke

12

截至Typescript 2.9版本,用户可以简单地添加:

"compilerOptions": {
    "resolveJsonModule": true
}

tsconfig.json之后,就可以使用json文件(并且在VSCode中会有很好的类型推断):

data.json:

{
    "cases": [
        {
            "foo": "bar"
        }
    ]
}

在您的Typescript文件中:

import { cases } from './data.json';


11

Angular 10

现在您应该编辑名为tsconfig.app.json(注意名称中的 "app")的文件。

在那里,您会找到 compilerOptions ,然后只需添加 resolveJsonModule: true

因此,例如,在全新的项目中,该文件应如下所示:

/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
  "extends": "./tsconfig.base.json",
  "compilerOptions": {
    "outDir": "./out-tsc/app",
    "types": [],
    "resolveJsonModule": true
  },
  "files": [
    "src/main.ts",
    "src/polyfills.ts"
  ],
  "include": [
    "src/**/*.d.ts"
  ]
}

8

对于 Angular 7 +,

1)将文件“typings.d.ts”添加到项目的根目录中(例如,src / typings.d.ts):

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

2)导入和访问JSON数据:

import * as data from 'path/to/jsonData/example.json';
...
export class ExampleComponent {
    constructor() {
        console.log(data.default);
    }

}

或者:

import data from 'path/to/jsonData/example.json';
...
export class ExampleComponent {
    constructor() {
        console.log(data);
    }

}

data.default让我困扰了好久。感谢提供完整的示例! - kevin_fitz
要注意JSON文件的路径,因为它与你导入文件的路径有关。例如,如果你在src/app/services/文件夹中有一个服务,并且你的JSON文件在src/assets/data/文件夹中,你必须像这样指定路径:../../assets/data/your.json - Adam Bogdan Boczek
它运行得很完美,但为什么需要 typings.d.ts 文件? - robert

6

在Angular7中,我只是简单地使用了

let routesObject = require('./routes.json');

我的routes.json文件看起来像这样

{

    "routeEmployeeList":    "employee-list",
    "routeEmployeeDetail":      "employee/:id"
}

您可以使用以下方法访问JSON项:
routesObject.routeEmployeeList

就是这样!;-) 所有其他选项都很hacky! 如果您使用TSLint会抛出一个reuqire错误 - 只需在类组件顶部添加declare var require: any;即可。 - Pedro Ferreira

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接