Импорт json файла в TypeScript
У меня есть 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"
Что я делаю неправильно?
Ответы
Ответ 1
Форма импорта и объявление модуля должны согласовать форму модуля, то, что он экспортирует.
Когда вы пишете (плохая практика для файлов JSON начиная с TypeScript 2.9 при настройке на совместимые форматы модулей see note)
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
дает вам объект, представляющий сам модуль, а не его экспортированные привязки.
Так почему ошибка? Потому что ты написал
import a = require("a.json");
a.primaryMain
И все же нет экспорта с именем primaryMain
, объявленного вашим "*.json"
.
Все это предполагает, что ваш загрузчик модулей предоставляет JSON в качестве экспорта default
, как предложено в вашей первоначальной декларации.
Примечание: Начиная с TypeScript 2.9, вы можете использовать флаг компилятора --resolveJsonModule
, чтобы TypeScript анализировал импортированные файлы .json
и предоставлял правильную информацию относительно их формы, устраняя необходимость в объявлении модуля с подстановочными знаками и валидации наличие файла. Это не поддерживается для определенных форматов целевого модуля.
Ответ 2
С TypeScript 2.9. + Вы можете просто импортировать JSON файлы с такими типами безопасности и intellisense, как это:
import colorsJson from '../colors.json';
console.log(colorsJson.primaryBright);
Обязательно добавьте эти параметры в раздел compilerOptions
вашего tsconfig.json
(документация):
"resolveJsonModule": true,
"esModuleInterop": true,
Примечания стороны:
- В Typescript 2.9.0 есть ошибка с этой функцией JSON, я думаю, что она исправлена в 2.9.1 или 2.9.2
- EsModuleInterop необходим только для импорта по умолчанию colorsJson. Если вы оставите значение false, вам придется импортировать его с помощью
import * as colorsJson from '../colors.json'
Ответ 3
Это легко использовать машинописную версию 2. 9+. Таким образом, вы можете легко импортировать JSON файлы в качестве атрибутов @kentor.
Но если вам нужно использовать более старые версии:
Вы можете получить доступ к файлам JSON более чем в режиме TypeScript. Во- первых, убедитесь, что ваш новый typings.d.ts
место такое же, как с include
свойства в вашем tsconfig.json
файле.
Если у вас нет свойства tsconfig.json
файле tsconfig.json
. Тогда ваша структура папок должна быть такой:
- 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
должны находиться в каталоге src
как описано в свойстве 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;
}
Легко импортировать в ваши файлы машинописных файлов:
import * as Config from 'config.json';
export class SomeClass {
public someMethod: void {
console.log(Config.address);
console.log(Config.port);
}
}
Но на этапе компиляции вы должны вручную скопировать файлы JSON в папку dist. Я просто добавляю свойство script к моей конфигурации package.json
:
{
"name" : "some project",
"scripts": {
"build": "rm -rf dist && tsc && cp src/config.json dist/"
}
}
Ответ 4
В файле определения TS, например typings.d.ts ', вы можете добавить эту строку:
declare module "*.json" {
const value: any;
export default value;
}
Затем добавьте это в свой файл машинописного текста (.ts): -
import * as data from './colors.json';
const word = (<any>data).name;
Ответ 5
Еще один способ пойти
const data: {[key: string]: any} = require('./data.json');
Это было то, что вы все еще можете определить тип json, если хотите, и вам не нужно использовать подстановочный знак.
Например, пользовательский тип JSON.
interface User {
firstName: string;
lastName: string;
birthday: Date;
}
const user: User = require('./user.json');
Ответ 6
Вышесказанное работает, если нет дочерних объектов. если у меня есть JSON, как
{"name": "name", "address": [ { "field1": "value", "field1": "value" }, { "field1": "value", "field1": "value" } ]}
Это не кодирование дочерних объектов JSON.