【问题标题】:Typescript compiler error when importing json file导入 json 文件时的 Typescript 编译器错误
【发布时间】:2016-01-02 05:58:54
【问题描述】:

所以代码很简单:

calls.json

{"SERVER":{
    "requests":{
      "one":"1"
    }
} }

文件.ts

import json = require('../static/calls.json');
console.log(json.SERVER);

生成的 javascript 是正确的,并且在运行节点 js 服务器时,控制台日志 json.SERVER 会打印 '{ requests: { one: '1' } }',这是应该的。

然而,打字稿编译器(commonjs)不知何故并不特别喜欢这种情况并抛出:“找不到模块'../static/calls.json'”。

当然我试过写一个 .d.ts 文件,像这样:

declare module '../static/calls.json'{
    var exp:any;
    export = exp;
}

这显然会抛出:“环境模块声明无法指定相对模块名称”。

我也尝试了不同的变体,例如:

declare module 'calls.json' {
    import * as json from '/private/static/calls.json';
    export = json;
}

然后要求:

import json = require('calls.json');

没有一个可以正常工作并且有自己的小编译错误:)

我想使用外部 .json 文件,因为我使用 commonjs 服务器端和 amd 客户端,并且我想要一个文件来加载常量。

【问题讨论】:

    标签: javascript json node.js typescript commonjs


    【解决方案1】:

    使用var 代替import

    var json = require('./calls.json');
    

    您正在加载 JSON 文件,而不是模块,因此在这种情况下不应使用 import。当使用var 时,require() 再次被视为普通函数。

    如果您使用的是 Node.js 定义,则一切都应该正常工作,否则需要定义 require

    【讨论】:

    • 这会起作用,尽管我使用的是 requirejs 客户端。这意味着在加载 requirejs 定义时,节点定义中声明的 var require 会导致问题,因为在 require.d.ts 中也声明了 var require...
    • 是的,当两个定义同时被引用时,这是预期的。在运行时也是如此。你永远不会同时使用两个require。快速的解决方案是让该文件不引用它们中的任何一个,而只使用declare var require: any;
    • @thoughtrepo 可以详细说明您的答案吗?从 Typescript 到 Babel 到 ES5 仍在寻找模块。我发现自己处于这种情况下,尽管故障安全直觉是将 json 导入为 var config = require('./config.json'),但 Typescript-Babel 仍然指示相同的“找不到模块 .config.json”错误消息。
    • 我收到错误“无法 lint::require 语句不是导入语句的一部分”。有人可以帮忙吗?
    • ts 不允许 var.
    【解决方案2】:

    如果使用webpack v2 已经与json-loader 打包,则可以使用import 语句来完成。

    注意这不是异步的

    import data from './data.json';//Note that this is not async
    

    另外,在您的 typings.d.ts 文件中添加以下 wildcard module 以避免打字稿错误:Cannot find module

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

    任何对async 导入感兴趣的人,请查看this article by 2uality

    【讨论】:

      【解决方案3】:

      另一种解决方案是将data.json更改为data.ts并像这样导出

      export default {
        "key" : {
          ...
        }
      }
      

      并按照您的预期导入:

      import { default as data } from './data'
      

      【讨论】:

      • 从'./data.ts'导入{默认为数据};
      • @phi 不确定是否需要“.ts”扩展名。
      【解决方案4】:

      TS 2.9 added support for well typed json imports。只需添加:

      {
        "compilerOptions": {
          "resolveJsonModule": true
        }
      }
      

      在您的tsconfig.jsonjsconfig.json 中。现在导入如:

      import json = require('../static/calls.json');
      

      import * as json from '../static/calls.json';
      

      应该得到解决并且也有正确的类型!

      【讨论】:

      • 不起作用看到这个github issue
      • @Max 为我工作。该修复已于 7 月 5 日合并到 master 中,现已在稳定版中提供。
      • 这只有在你的目标是commonjs时才有效,如果你想输出其他任何东西它就不起作用
      • 无论target如何都能完美运行。我 and many others 确实必须重新启动 VS Code 才能让 Intellisense 停止吠叫。
      【解决方案5】:

      Typescript 2.9 开始,您可以在本地导入 JSON 文件,而无需任何额外的 hack/loader。

      以下摘录自上述链接复制。

      ...TypeScript 现在可以在使用 moduleResolution 的节点策略时将 JSON 文件作为输入文件导入。这意味着您可以在他们的项目中使用 json 文件,而且它们的类型会很好!

      ./src/settings.json

      {
          "dry": false,
          "debug": 
      

      ./src/foo.ts

      import settings from "./settings.json";
      
      settings.debug === true;  // Okay
      settings.dry === 2;       // Error! Can't compare a `boolean` and `number`
      

      【讨论】:

        【解决方案6】:
        For Angular 6 it can work with simple HTTP get call as below
        
        Service
        //interface, could be Array , object 
        export interface ResultJSON{
        
        }
         //Read JSON file for 3DWide
          getJSON() {
            return this.http.get(this.filepathUrl);
          }
        
        Component :import both service and interface and use as below
        resultJSON :ResultJSON;
         this
              .testService
              .getJSON()
              .subscribe((data: ResultJSON) => {
                   this.resultJSON= data;
                   console.log(this.resultJSON); 
        
        
                 });
        

        【讨论】:

        • 需要不必要的http请求
        【解决方案7】:

        2021 年。 我想导入 package.json 版本

        对于 Angular 的人来说,如果你被卡住了。要使用导入吗?

        打开 tsconfig.json 并添加 compilerOptions

        "resolveJsonModule": true,
        

        就是这样,你可以使用它

        import { version } from '../package.json';
        

        【讨论】:

          猜你喜欢
          • 2014-03-31
          • 2017-06-17
          • 2019-05-23
          • 2020-10-23
          • 1970-01-01
          • 1970-01-01
          • 2017-08-03
          • 1970-01-01
          • 2019-12-11
          相关资源
          最近更新 更多