Как правильно импортировать JSON файл в TypeScript? Ошибка при импорте
Пошаговое решение проблемы импорта JSON в TypeScript
Ошибка, которую вы получаете, связана с тем, что по умолчанию TypeScript не умеет импортировать JSON файлы. Это сделано по соображениям безопасности и типизации. Однако есть несколько способов решить эту проблему. Рассмотрим самый правильный и популярный.
Способ 1: Включение resolveJsonModule (рекомендуемый)
Это самый простой и правильный способ. Добавьте в ваш tsconfig.json две опции:
{
"compilerOptions": {
"resolveJsonModule": true,
"esModuleInterop": true,
// ... остальные настройки
}
}
Важно: esModuleInterop нужен для корректной работы импорта по умолчанию (import config from './config.json'). Без него придётся использовать import * as config from './config.json'.
После добавления этих настроек перезапустите компилятор или ваш редактор кода (VS Code). Теперь импорт будет работать:
import config from './config.json';
console.log(config.apiUrl); // "https://api.example.com"
console.log(config.port); // 3000
console.log(config.debug); // true
TypeScript автоматически выведет типы из JSON. Например, config.apiUrl будет иметь тип string, config.port — number, config.debug — boolean.
Способ 2: Явное объявление модуля (для сложных случаев)
Если по каким-то причинам вы не можете использовать resolveJsonModule, можно объявить модуль для JSON файлов вручную. Создайте файл json.d.ts (или declarations.d.ts) в корне проекта:
declare module "*.json" {
const value: any;
export default value;
}
Но этот способ менее предпочтителен, так как теряется типизация (все поля будут any).
Способ 3: Чтение через fs (для Node.js)
Если вы работаете в среде Node.js, можно прочитать JSON файл через модуль fs:
import * as fs from 'fs';
import * as path from 'path';
const configPath = path.join(__dirname, 'config.json');
const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
console.log(config.apiUrl);
Этот способ даёт полный контроль, но требует больше кода и не даёт статической типизации без дополнительных усилий.
Важные замечания
- Пути: JSON файл должен быть в той же директории или путь должен быть указан относительно файла, из которого импортируете.
- Кэширование: При использовании
resolveJsonModuleJSON импортируется как модуль, поэтому изменения в JSON файле потребуют перезапуска компилятора (в dev режиме — перезагрузки черезts-node --watchили nodemon). - Большие файлы: Для больших JSON файлов (например, базы данных) лучше использовать
fsс асинхронным чтением, чтобы не блокировать поток.
Рекомендую использовать первый способ (resolveJsonModule), так как он наиболее идиоматичен для TypeScript и сохраняет типизацию.
Альтернативный подход: создание TypeScript конфигурационного файла
Если вам нужно импортировать конфигурацию, возможно, стоит задуматься о том, чтобы хранить её в TypeScript файле вместо JSON. Это даёт несколько преимуществ:
// config.ts
export const config = {
apiUrl: "https://api.example.com",
port: 3000,
debug: true
} as const; // as const для строгой типизации
Тогда импорт будет работать без каких-либо дополнительных настроек:
import { config } from './config';
console.log(config.apiUrl); // тип string
console.log(config.port); // тип number (точнее, литеральный тип 3000)
Преимущества:
- Не нужно настраивать
resolveJsonModule - Полная типизация с возможностью использования TypeScript фич (enum, интерфейсы, вычисляемые значения)
- Можно использовать комментарии и логику
- Поддержка рефакторинга и автодополнения в IDE
Недостатки:
- Нельзя использовать в проектах, где конфигурация должна быть в чистом JSON (например, для внешних сервисов)
- Требует компиляции TypeScript в JavaScript перед использованием
Этот подход особенно удобен, когда конфигурация содержит сложные структуры данных или требует вычислений при инициализации. Для простых статических данных JSON остаётся хорошим выбором, но с правильной настройкой TypeScript, описанной в первом ответе.