Avatar ·

Ошибка TS2304: Cannot find name 'require' в TypeScript — как исправить?

Привет! Я только начал изучать TypeScript и пытаюсь подключить Node.js модуль fs для работы с файлами. Пишу простой скрипт, который читает файл: ```typescript const fs = require('fs'); fs.readFile('test.txt', 'utf8', (err, data) => { if (err) throw err; console.log(data); }); ``` Но при компиляции TypeScript выдает ошибку: `error TS2304: Cannot find name 'require'`. Я использую Node.js v18 и TypeScript v5. Установил пакеты `@types/node`, но ошибка всё равно остаётся. Подскажите, что я делаю не так? Нужно ли как-то специально настраивать tsconfig.json или устанавливать дополнительные типы? Видел на Stack Overflow похожие вопросы, но решения там разрозненные. Хотелось бы понять, в чём корень проблемы: то ли это из-за того, что TypeScript не знает про `require`, то ли я неправильно импортирую модули. Заранее спасибо! <<>>

Причина ошибки

Ошибка TS2304: Cannot find name 'require' возникает потому, что TypeScript по умолчанию работает в режиме модулей ES (ES Modules), где вместо require() используется синтаксис import ... from .... Функция require — это специфичная для CommonJS (Node.js) глобальная функция, и TypeScript не знает о её существовании, пока вы явно не укажете это в настройках.

Решение 1: Использовать синтаксис ES-модулей (рекомендуется)

Самый правильный способ — перейти на современный синтаксис import:

import * as fs from 'fs';
// или для конкретных функций:
import { readFile } from 'fs';

readFile('test.txt', 'utf8', (err, data) => {
  if (err) throw err;
  console.log(data);
});

Для этого в tsconfig.json должны быть настроены:

{
  "compilerOptions": {
    "module": "ESNext", // или "CommonJS", "ES2020"
    "moduleResolution": "node",
    "esModuleInterop": true, // для совместимости с CommonJS-модулями
    "types": ["node"]
  }
}

Решение 2: Разрешить использование require (для CommonJS-проектов)

Если вы работаете в проекте, который использует CommonJS (например, старый Node.js проект), вы можете добавить объявление типа для require:

// В корне проекта создайте файл declaration.d.ts
declare var require: NodeRequire;

Или проще — установите @types/node и добавьте в tsconfig:

{
  "compilerOptions": {
    "types": ["node"]
  }
}

После этого TypeScript будет знать о require, module, __dirname и других глобальных переменных Node.js.

Решение 3: Настройка tsconfig для конкретного типа модулей

Если вы хотите оставить require, но при этом использовать ES-модули в остальном коде, укажите в tsconfig:

{
  "compilerOptions": {
    "module": "CommonJS",
    "moduleResolution": "node",
    "esModuleInterop": true
  }
}

Важно: При использовании module: "CommonJS" TypeScript будет компилировать import в require, но вы всё равно сможете писать require напрямую.

Проверка установки @types/node

Убедитесь, что пакет установлен корректно:

npm install --save-dev @types/node

И что в tsconfig.json есть строка "types": ["node"]. Без этого TypeScript не подключит типы Node.js.

Что выбрать новичку?

  • Если вы пишете новый проект — используйте синтаксис import (Решение 1). Это современный стандарт.
  • Если вы переписываете старый JS-код на TypeScript — используйте Решение 2 (с объявлением require).
  • Если вы работаете с учебными примерами из интернета, где используют require — подойдёт Решение 3.

После любого из этих решений ошибка TS2304 исчезнет, и вы сможете использовать файловую систему и другие модули Node.js.

<<>>

Альтернативный подход: Использование динамического импорта

Если вы не хотите менять весь код на import, но при этом хотите оставаться в рамках ES-модулей, можно использовать динамический импорт с require через обёртку:

// Создайте вспомогательную функцию
function requireModule(name: string) {
  return require(name);
}

const fs = requireModule('fs');
fs.readFile('test.txt', 'utf8', (err, data) => {
  if (err) throw err;
  console.log(data);
});

Этот подход не самый элегантный, но он работает, если вы не хотите трогать tsconfig. Однако помните: такой код будет хуже поддерживаться и не даст преимуществ статической типизации для импортируемого модуля.

Дополнительная рекомендация

Если вы используете современную версию Node.js (v16+), рассмотрите переход на ECMAScript Modules (ESM) полностью. Для этого:

  • Добавьте "type": "module" в package.json
  • Переименуйте файлы в .mts (TypeScript для ESM)
  • Используйте import fs from 'fs' (работает напрямую с ESM)

Это избавит вас от проблем с require раз и навсегда.