web-dev-qa-db-ja.com

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として使います。しかし、私はエラーが出ます - Property 'primaryMain' does not exist on type 'typeof "*.json"

何がおかしいのですか?

58
Sooraj Chandran

インポートフォームとモジュール宣言は、エクスポートするものについて、モジュールの形状について合意する必要があります。

書くとき

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

.jsonで終わる指定子を持つすべてのモジュールには、defaultという名前の単一のanyという名前のエクスポートがあります。

このようなモジュールを消費する方法はいくつかあります。

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はモジュール自身を表すオブジェクトとそのエクスポートされたバインディングをnotします。

それではなぜエラー?書いたから

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

それでも、あなたの"*.json"によって宣言されたprimaryMainという名前のエクスポートはありません。

これはすべて、元の宣言で示されているように、モジュールローダーがJSONをdefaultエクスポートとして提供していることを前提としています。

38
Aluan Haddad

TypeScript 2.9。+では、型安全性とインテリセンスを持つJSONファイルを次のように単純にインポートできます。

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

これらの設定を必ずtsconfig.jsoncompilerOptionsセクションに追加してください( documentation ):

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

サイドノート:

  • TypeScript 2.9.0にはこのJSON機能のバグがあり、2.9.1または2.9.2で修正されたと思います
  • EsModuleInteropは、colorsJsonのデフォルトのインポートにのみ必要です。 falseに設定したままにしておくと、import * as colorsJson from '../colors.json'を使用してインポートする必要があります。
125
kentor

TypeScriptバージョン2.9以降を使うのは簡単です。そのため、JSONファイルを @kentor decribed として簡単にインポートできます。

しかし、あなたが古いバージョンを使う必要があるならば:

JSONファイルにもっとTypeScriptでアクセスすることができます。まず、新しいtypings.d.tsの場所が、tsconfig.jsonファイルのincludeプロパティと同じであることを確認してください。

tsconfig.jsonファイルにincludeプロパティがない場合それからあなたのフォルダー構造はそのようになっているはずです。

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

tsconfig.jsonincludeプロパティがあるとします。

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

それであなたのtypings.d.tssrcプロパティに記述されているように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設定にスクリプトプロパティを追加するだけです。

{
    "name"   : "some project",
    "scripts": {
        "build": "rm -rf dist && tsc && cp src/config.json dist/"
    }
}
8
Fırat KÜÇÜK

TS定義ファイル内。 typings.d.ts`、この行を追加することができます:

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

次にTypeScript(.ts)ファイルにこれを追加します。 - /

import * as data from './colors.json';
const Word = (<any>data).name;
3
Mehadi Hassan