TypeScriptでのjsonファイルのインポート


146

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'はタイプ 'typeof "* .json"に存在しません


3
モジュール宣言とインポートフォームが一致しません。
Aluan Haddad

2
例を見せていただけませんか?私はtypescript noobです。
Sooraj 2018

回答:


93

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

作成するとき(互換性のあるモジュール形式対象とする場合のTypeScript 2.9以降のJSONのインポートの次善策)を参照してください

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

それでも、でprimaryMain宣言された名前のエクスポートはありません"*.json"

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

注: TypeScript 2.9以降、--resolveJsonModuleコンパイラフラグを使用してTypeScriptにインポートされた.jsonファイルを分析させ、その形状に関する正しい情報を提供して、ワイルドカードモジュール宣言の必要をなくし、ファイルの存在を検証できます。これは、特定のターゲットモジュール形式ではサポートされていません。


1
ローダーに依存する@Royi。リモートファイルについては、使用を検討してくださいawait import('remotepath');
Aluan Haddad

26
スクロールし続けると、以下の最新の回答が得られます。
jbmusso

@jbmusso TypeScriptの後のバージョンで導入された改善に関するいくつかの情報を追加しましたが、この回答は概念的なものであるため、古くはないと思います。しかし、私はさらなる改善のための提案を受け入れています。
Aluan Haddad

1
リスクとしては、回答の最初の行を単にコピー/貼り付けて、根本的な原因ではなく、症状のみを修正できるというリスクがあります。@kentorの回答の方が詳細がわかり、より完全な回答が得られると思います。回答の上にノートを移動することをお勧めします。これは、現時点でこの問題に取り組むための正しい方法であることを明確に示しています。
jbmusso

@Atombitは明らかに、私を含む多くの人々のために働きました。受け入れられた回答に反対票を投じる前に、何が機能していないのか説明してください。
アルアンハダッド

267

TypeScript 2.9。+を使用すると、次のようにタイプセーフとインテリセンスを備えたJSONファイルをインポートできます。

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

ドキュメント)のcompilerOptionsセクションにこれらの設定を必ず追加してください:tsconfig.json

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

サイドノート:

  • Typescript 2.9.0にはこのJSON機能のバグがあり、2.9.2で修正されました
  • esModuleInteropは、colorsJsonのデフォルトのインポートにのみ必要です。falseに設定したままにすると、次のようにインポートする必要がありますimport * as colorsJson from '../colors.json'

17
必ずしも必要ではありませんがesModuleInterop、そうする必要がありますimport * as foo from './foo.json';- esModuleInteropこれを有効にしようとしたときに他の問題が発生していました。
mpen 2018

1
あなたは正しい、私はそれをサイドノートとして追加すべきだった:-)。
ケンター2018

10
注:オプション「resolveJsonModule」は「ノード」モジュール解決戦略なしでは指定できないため、にもを"moduleResolution": "node"挿入する必要がありますtsconfig.json。また*.json、インポートするファイルが内にある必要があるという欠点もあります"rootDir"。出典:blogs.msdn.microsoft.com/typescript/2018/05/31/...
ベニー・ノイゲバウアー

2
@mpenは正しいですimport * as foo from './foo.json'が、間違ったインポートフォームです。それはする必要がありますimport foo = require('./foo.json');使用しない場合esModuleInterop
Aluanハダッドを

1
私は必要な部分だけだった"resolveJsonModule": trueし、すべてが順調です
マイケル・エリオット

10

typescriptバージョン2.9以降は簡単に使用できます。そのため、@ kentorが記述したとおりに JSONファイルを簡単にインポートできます。

しかし、古いバージョンを使用する必要がある場合:

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

tsconfig.jsonファイルにincludeプロパティがない場合。次に、フォルダ構造は次のようになります。

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

しかし、あなたの中にincludeプロパティがある場合tsconfig.json

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

次に、プロパティで説明されているようにディレクトリにあるtypings.d.tsはずですsrcinclude

+ 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/"
    }
}

rm -rfはLinux / Unixのものですか、それとも古いWindurzでも機能しますか?
コーディ

ありがとう、私のtypings.d.tsは場違いでした。/ srcに移動するとすぐにエラーメッセージが消えました。
Gi1ber7

1
@Codyそれは確かにLinux / Unixのものだけです。
Maxie Berkmann

7

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;

2
これは非常に悪い考えです。
Aluan Haddad

3
なぜそれが悪いのか説明してもらえますか??? 私はタイプスクリプトの専門家ではありません。@AluanHaddad
Mehadi Hassan

5
の型アサーションanyは2つのことを言います。1)定義上、一見して誤って宣言またはインポートした。あなたの必要があります決していかなる状況の下であなた自身が宣言したモジュールのインポート時に型アサーションを置く必要はありません。2)実行時に何らかの方法でこれを実行する非常識なローダーがあるとしても、神々は禁じますが、それでも、非常に混乱しやすく、特定の形状のモジュールにアクセスするための最ももろい方法です。* as x fromそしてx from、OPにあるものよりもランタイムのミスマッチがさらに大きくなります。真剣にこれをしないでください。
Aluan Haddad

5
ご回答ありがとうございます。はっきり分かりました。@AluanHaddad
Mehadi Hassan

2

別の方法

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

これはまだjsonタイプを定義できるため、ワイルドカードを使用する必要はありません。

たとえば、カスタムタイプjsonです。

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

2
これは質問とは関係がなく、悪い習慣でもあります。
Aluan Haddad

0

多くの場合、Node.jsアプリケーションでは.jsonが必要です。TypeScript 2.9では、-resolveJsonModuleを使用して、.jsonファイルのインポート、タイプの抽出、および.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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.