Ошибка TS2304: Cannot find name 'require' в TypeScript — как исправить?
Причина ошибки
Ошибка 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 раз и навсегда.