web-dev-qa-db-fra.com

Importer un fichier json dans TypeScript

J'ai un fichier JSON qui ressemble à ce qui suit:

{

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

J'essaie de l'importer dans un fichier .tsx. Pour cela, j'ai ajouté ceci à la définition de type:

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

Et je l'importe comme ça.

import colors = require('../colors.json')

Et dans le fichier, j'utilise la couleur primaryMain comme colors.primaryMain. Cependant, je reçois une erreur - Property 'primaryMain' does not exist on type 'typeof "*.json"

Qu'est-ce que je fais mal?

76
Sooraj Chandran

Le formulaire d'importation et la déclaration du module doivent s'accorder sur la forme du module, sur ce qu'il exporte.

Lorsque vous écrivez (pratique recommandée pour les fichiers JSON depuis TypeScript 2.9 lorsque vous ciblez des formats de module compatibles voir la note )

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

Vous déclarez que tous les modules dont le spécificateur se termine par .json ont une seule exportation nommée default de type any.

Il existe plusieurs façons de consommer un tel module, notamment

import a from "a.json";
a.primaryMain

et

import * as a from "a.json";
a.default.primaryMain

et

import {default as a} from "a.json";
a.primaryMain

et

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

La première forme est la meilleure et le sucre syntaxique qu’elle exploite est la raison même pour laquelle JavaScript exporte default.

Cependant, j'ai mentionné les autres formulaires pour vous donner une idée de ce qui ne va pas. Portez une attention particulière au dernier. require vous donne un objet représentant le module lui-même et pas ses liaisons exportées.

Alors pourquoi l'erreur? Parce que vous avez écrit

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

Et pourtant, il n'y a pas d'exportation nommée primaryMain déclarée par votre "*.json".

Tout cela suppose que votre chargeur de modules fournisse le JSON comme exportation default comme suggéré par votre déclaration d'origine.

Remarque: Depuis TypeScript 2.9, vous pouvez utiliser le drapeau --resolveJsonModule du compilateur pour que TypeScript analyse les importations importées .json fichiers et fournissent des informations correctes sur leur forme, évitant ainsi la nécessité d’une déclaration de module générique et validant la présence du fichier. Ceci n'est pas pris en charge pour certains formats de module cible.

49
Aluan Haddad

Avec TypeScript 2.9. +, Vous pouvez simplement importer des fichiers JSON avec sécurité typographique et intellisense comme ceci:

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

Assurez-vous d’ajouter ces paramètres dans la section compilerOptions de votre tsconfig.json ( documentation ):

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

Notes annexes:

  • TypeScript 2.9.0 a un bug avec cette fonctionnalité JSON, je crois qu’il a été corrigé avec la version 2.9.1 ou 2.9.2
  • EsModuleInterop n'est nécessaire que pour l'importation par défaut de colorsJson. Si vous le laissez sur false, vous devez l'importer avec import * as colorsJson from '../colors.json'
157
kentor

Il est facile d'utiliser TypeScript version 2.9+. Ainsi, vous pouvez facilement importer des fichiers JSON en tant que @ (kentor décrit) .

Mais si vous devez utiliser des versions plus anciennes:

Vous pouvez accéder aux fichiers JSON de manière plus typée. Tout d’abord, assurez-vous que votre nouvel emplacement typings.d.ts est identique à celui de la propriété include de votre fichier tsconfig.json.

Si vous n'avez pas de propriété include dans votre fichier tsconfig.json. Ensuite, votre structure de dossier devrait être comme ça:

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

Mais si vous avez une propriété include dans votre tsconfig.json:

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

Ensuite, votre typings.d.ts devrait être dans le répertoire src comme décrit dans la propriété include.

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

Comme dans beaucoup de réponses, vous pouvez définir une déclaration globale pour tous vos fichiers JSON.

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

mais je préfère une version plus typée de ceci. Par exemple, supposons que vous ayez le fichier de configuration config.json comme ça:

{
    "address": "127.0.0.1",
    "port"   : 8080
}

Ensuite, nous pouvons déclarer un type spécifique pour cela:

declare module 'config.json' {
    export const address: string;
    export const port: number;
}

Il est facile d'importer dans vos fichiers TypeScript:

import * as Config from 'config.json';

export class SomeClass {
    public someMethod: void {
        console.log(Config.address);
        console.log(Config.port);
    }
}

Mais en phase de compilation, vous devez copier les fichiers JSON dans votre dossier dist manuellement. Je viens d'ajouter une propriété de script à ma configuration package.json:

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

Dans votre fichier de définition TS, par exemple, typings.d.ts`, vous pouvez ajouter cette ligne:

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

Ajoutez ensuite ceci dans votre fichier TypeScript (.ts): -

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

Une autre façon de faire

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

C’est là que vous pouvez toujours définir le type JSON que vous voulez et ne pas utiliser de caractère générique.

Par exemple, tapez json personnalisé.

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