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?
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.
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:
import * as colorsJson from '../colors.json'
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/"
}
}
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;
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');