Импорт файла 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"

Что я делаю неправильно?

18 ответов

Решение

Форма импорта и декларация модуля должны согласовать форму модуля, то, что он экспортирует.

Когда ты пишешь

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.+ Вы можете просто импортировать файлы JSON с такими типами безопасности и intellisense, как это:

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

Обязательно добавьте эти настройки в ваш файл 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'

У меня были проблемы с замедлением tsc или нехваткой памяти при импорте больших файлов напрямую с помощью resolveJsonModule. Чтение файла во время выполнения не имеет этих проблем.

      import fs from 'fs'
var dataArray = JSON.parse(fs.readFileSync('data.json', 'utf-8'))

В моем случае мне нужно было изменить tsconfig.node.json:

      {
  "compilerOptions": {
    ...
    "resolveJsonModule": true
  },
  "include": [..., "colors.json"]
}

И импортировать так:

      import * as colors from './colors.json'

Или вот так:

      import colors from './colors.json'

с "esModuleInterop": правда

Легко использовать машинопись версии 2.9+. Таким образом, вы можете легко импортировать файлы JSON, как описано @kentor.

Но если вам нужно использовать более старые версии:

Вы можете получить доступ к файлам JSON более TypeScript способом. Во-первых, убедитесь, что ваш новый typings.d.ts расположение такое же, как с include собственность в вашем tsconfig.json файл.

Если у вас нет свойства include в вашем 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 вручную. Я просто добавляю свойство скрипта в мой package.json конфигурация:

{
    "name"   : "some project",
    "scripts": {
        "build": "rm -rf dist && tsc && cp src/config.json dist/"
    }
}

Вы должны добавить

      "resolveJsonModule": true

как часть compilerOptions в tsconfig.json.

В приложении Angular (typescript) мне нужно было включить .jsonфайл в моем . Для этого мне пришлось установить две опции в tsconfig:

      {
  "compilerOptions": {
    "moduleResolution": "node",
    "resolveJsonModule": true
  }
}

Затем я мог бы импортировать свой файл json в environment.ts:

      import { default as someObjectName } from "../some-json-file.json";

В вашем файле определения 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;

Вы можете импортировать файл JSON без изменения tsconfig, вы явно указываете, что импортируете JSON.

      import mydata  from './mydataonfile.json' assert { type: "json" };

Я знаю, что это не полностью отвечает на вопрос, но многие люди приходят сюда, чтобы узнать, как загрузить JSON непосредственно из файла.

Часто в приложениях Node.js требуется.json. В TypeScript 2.9 --resolveJsonModule позволяет импортировать, извлекать типы и создавать файлы.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

Еще один способ пойти

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

Это было то, что вы все еще можете определить тип json, если хотите, и вам не нужно использовать подстановочный знак.

Например, пользовательский тип JSON.

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

В TypeScript 5.3 появились атрибуты импорта , ранее известные как утверждения импорта , которые могут предоставлять информацию об ожидаемом формате импортируемого модуля во время выполнения.

Атрибуты импорта гарантируют, что модуль импортируется в правильном формате. Это означает.jsonфайл, который на самом деле содержит работоспособный код JavaScript, определенно интерпретируется как JSON.

      import colors from "./colors.json" with { type: "json" };

Включить "resolveJsonModule": true в tsconfig.json файл и реализовать, как показано ниже, для меня это работает:

const config = require('./config.json');

Обратите внимание, что если вы используете способы @kentor

Обязательно добавьте эти настройки в раздел compilerOptions вашего tsconfig.json (документация ):

Вам нужно добавить --resolveJsonModule а также --esModuleInterop за tsc команда для компиляции файла TypeScript.

Пример: tsc --resolveJsonModule --esModuleInterop main.ts

в моем случае мне пришлось изменить: "include": ["src"]к "include": ["."]в дополнение к "resolveJsonModule":trueпотому что я пытался импортировать manifest.jsonиз корня проекта, а не из ./src

добавьте это в свой tsconfig.json файл:

      {
  "compilerOptions": {
    "resolveJsonModule": true
  }
}


Вы должны иметь это в своем tsconfig.json

      {
  "compilerOptions":{
    "resolveJsonModule": true,
    "esModuleInterop": true
  },
}

requireэто распространенный способ загрузки файла JSON в Node.js.

Другие вопросы по тегам