JSON-Datei in TypeScript importieren
Ich habe eine JSON-Datei, die wie folgt aussieht:
{
"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"
}
Ich versuche, es in eine .tsx-Datei zu importieren. Dafür habe ich dies der Typdefinition hinzugefügt:
declare module "*.json" {
const value: any;
export default value;
}
Und ich importiere es so.
import colors=require('../colors.json')
Und in der Datei verwende ich die Farbe primaryMain als colors.primaryMain. Allerdings erhalte ich einen Fehler:
Eigenschaft 'primaryMain' existiert nicht auf dem Typ 'typeof "*.json"'
Antwort #1
Mit TypeScript 2.9.+ können Sie JSON-Dateien einfach importieren und dabei Vorteile wie Typsicherheit und Intellisense nutzen, indem Sie Folgendes tun:
import colorsJson from '../colors.json'; // This import style requires "esModuleInterop", see "side notes"
console.log(colorsJson.primaryBright);
Stellen Sie sicher, dass Sie diese Einstellungen im Abschnitt compilerOptions Ihrer tsconfig.json (Dokumentation) hinzufügen:
"resolveJsonModule": true,
"esModuleInterop": true,
Seitenhinweise:
- Typescript 2.9.0 hat einen Fehler mit dieser JSON-Funktion, er wurde mit 2.9.2 behoben
- Das esModuleInterop ist nur für den Standardimport von colorsJson notwendig. Wenn Sie es auf false belassen, müssen Sie es mit
import * as colorsJson from '../colors.json'importieren.
Antwort #2
Das Importformular und die Modulerklärung müssen sich über die Form des Moduls einig sein, darüber, was es exportiert.
Wenn Sie schreiben (eine suboptimale Vorgehensweise zum Importieren von JSON seit TypeScript 2.9 beim Ziel von kompatiblen Modulformatensiehe Hinweis)
declare module "*.json" {
const value: any;
export default value;
}
Sie geben an, dass alle Module, die einen Bezeichner haben, der auf .json endet, einen einzelnen Export mit dem Namen default haben.
Es gibt mehrere Möglichkeiten, ein solches Modul korrekt zu verwenden, einschließlich
import a from "a.json";
a.primaryMain
und
import * as a from "a.json";
a.default.primaryMain
und
import {default as a} from "a.json";
a.primaryMain
und
import a = require("a.json");
a.default.primaryMain
Die erste Form ist die beste und der syntaktische Zucker, den sie verwendet, ist der eigentliche Grund, warum JavaScript default Exporte hat.
Ich habe jedoch die anderen Formen erwähnt, um Ihnen einen Hinweis darauf zu geben, was schiefläuft. Achten Sie besonders auf die letzte. require liefert Ihnen ein Objekt, das das Modul selbst darstellt und nicht seine exportierten Bindungen.
Also warum der Fehler? Weil du geschrieben hast
import a = require("a.json");
a.primaryMain
Und doch gibt es keinen Export namens primaryMain, der von Ihrer "*.json" deklariert wird.
All dies setzt voraus, dass Ihr Modul-Loader das JSON wie in Ihrer ursprünglichen Deklaration vorgeschlagen als default-Export bereitstellt.
Hinweis: Seit TypeScript 2.9 können Sie das Compiler-Flag --resolveJsonModule verwenden, damit TypeScript importierte .json-Dateien analysiert und korrekte Informationen über ihre Struktur bereitstellt, wodurch die Notwendigkeit einer Wildcard-Moduldeklaration entfällt und das Vorhandensein der Datei überprüft wird. Dies wird für bestimmte Zielmodulformate nicht unterstützt.
Antwort #3
So importieren Sie eine JSON-Datei zur Laufzeit
import fs from 'fs'
var dataArray = JSON.parse(fs.readFileSync('data.json', 'utf-8'))
Auf diese Weise vermeiden Sie Probleme mit tsc, das beim Importieren großer Dateien verlangsamt oder den Speicher ausgeht, was passieren kann, wenn resolveJsonModule verwendet wird.
Antwort #4
In meinem Fall musste ich tsconfig.node.json ändern:
{
"compilerOptions": {
...
"resolveJsonModule": true
},
"include": [..., "colors.json"]
}
Und so importieren:
import * as colors from './colors.json'
Oder so:
import colors from './colors.json'
mit "esModuleInterop": true
Antwort #5
Es ist einfach, TypeScript Version 2.9+ zu verwenden. Sie können also problemlos JSON-Dateien importieren, wie @kentor beschrieben hat.
Aber wenn Sie ältere Versionen verwenden müssen:
Sie können auf JSON-Dateien auf eine typischer TypeScript-Weise zugreifen. Stellen Sie zunächst sicher, dass sich Ihr neuer typings.d.ts-Ort an derselben Stelle befindet wie die include-Eigenschaft in Ihrer tsconfig.json-Datei.
Wenn Sie keine Include-Eigenschaft in Ihrer tsconfig.json Datei haben, sollte Ihre Ordnerstruktur so aussehen:
- app.ts
+ node_modules/
- package.json
- tsconfig.json
- typings.d.ts
Aber wenn Sie eine include-Eigenschaft in Ihrer tsconfig.json haben:
{
"compilerOptions": {
},
"exclude" : [
"node_modules",
"**/*spec.ts"
], "include" : [
"src/**/*"
]
}
Dann sollte Ihre typings.d.ts im src-Verzeichnis wie im include-Eigenschaft beschrieben sein
+ node_modules/
- package.json
- tsconfig.json
- src/
- app.ts
- typings.d.ts
Wie in vielen der Antworten können Sie eine globale Deklaration für alle Ihre JSON-Dateien definieren.
declare module '*.json' {
const value: any;
export default value;
}
aber ich bevorzuge eine stärker typisierte Version davon. Zum Beispiel sagen wir, du hast eine Konfigurationsdatei config.json wie diese:
{
"address": "127.0.0.1",
"port" : 8080
}
Dann können wir einen bestimmten Typ dafür deklarieren:
declare module 'config.json' {
export const address: string;
export const port: number;
}
Es ist einfach, in Ihre TypeScript-Dateien zu importieren:
import * as Config from 'config.json';
export class SomeClass {
public someMethod: void {
console.log(Config.address);
console.log(Config.port);
}
}
Aber in der Kompilierungsphase sollten Sie JSON-Dateien manuell in Ihren dist-Ordner kopieren. Ich füge einfach eine Skript-Eigenschaft zu meiner package.json-Konfiguration hinzu:
{
"name" : "some project",
"scripts": {
"build": "rm -rf dist && tsc && cp src/config.json dist/"
}
}
Antwort #6
In einer Angular (TypeScript) App musste ich eine .json Datei in meine environment.ts einfügen. Dazu musste ich zwei Optionen in tsconfig setzen:
{
"compilerOptions": {
"moduleResolution": "node",
"resolveJsonModule": true
}
}
Dann könnte ich meine JSON-Datei in die environment.ts importieren:
import { default as someObjectName } from "../some-json-file.json";
Antwort #7
Oft wird in Node.js-Anwendungen eine .json-Datei benötigt. Mit TypeScript 2.9 erlaubt --resolveJsonModule das Importieren, Extrahieren von Typen und Erzeugen von .json-Dateien.
Beispiel #
// 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
}von: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-9.html
Antwort #8
Du solltest hinzufügen
"resolveJsonModule": true
als Teil von compilerOptions zu tsconfig.json.
Antwort #9
Sie können eine JSON-Datei importieren, ohne tsconfig zu ändern, indem Sie ausdrücklich angeben, dass Sie JSON importieren.
import mydata from './mydataonfile.json' assert { type: "json" };
Ich weiß, dass dies die Frage nicht vollständig beantwortet, aber viele Menschen kommen hierher, um zu erfahren, wie man JSON direkt aus einer Datei lädt.
Antwort #10
TypeScript 5.3 führte Importattribute ein, früher bekannt als Importaussagen, die Informationen über das erwartete Format eines importierten Moduls zur Laufzeit bereitstellen können.
Import-Attribute stellen sicher, dass ein Modul im richtigen Format importiert wird. Das bedeutet, dass eine .json-Datei, die tatsächlich ausführbaren JavaScript-Code enthält, definitiv als JSON interpretiert wird.
import colors from "./colors.json" with { type: "json" };
