Avatar ·

Ошибка "Unknown file extension ".ts"" при запуске TypeScript в Node.js

Привет! Я новичок в TypeScript и пытаюсь запустить свой первый проект. Установил Node.js, создал файл `index.ts` с простым кодом: ```typescript const greet = (name: string): string => { return `Hello, ${name}!`; }; console.log(greet("World")); ``` Пытаюсь запустить его через `node index.ts`, но получаю ошибку: `TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for C:\projects\test\index.ts` Я уже установил TypeScript глобально через `npm install -g typescript`, но это не помогло. Пробовал также устанавливать `ts-node` — ошибка осталась. Мой `package.json` выглядит так: ```json { "name": "test-project", "version": "1.0.0", "type": "module" } ``` Подскажите, что я делаю не так? Как правильно настроить проект, чтобы запускать TypeScript файлы? Очень хочется разобраться, но в документации запутался окончательно. <<>>

Почему возникает эта ошибка?

Node.js по умолчанию не понимает TypeScript (.ts файлы). Он работает только с JavaScript (.js, .mjs, .cjs). Ошибка "Unknown file extension" возникает именно потому, что вы пытаетесь напрямую запустить .ts файл через node, а не через компилятор TypeScript или специальный рантайм.

Решение 1: Компиляция через tsc (рекомендуется для production)

Самый правильный подход — скомпилировать TypeScript в JavaScript, а затем запускать JS-файл.

// 1. Устанавливаем TypeScript локально в проект
npm install --save-dev typescript

// 2. Создаём конфигурационный файл tsconfig.json
npx tsc --init

В tsconfig.json обязательно укажите:

  • "target": "ES2020" — версия JS, в которую компилируем
  • "module": "ESNext" или "CommonJS" — система модулей
  • "outDir": "./dist" — папка для скомпилированных файлов
  • "rootDir": "./src" — папка с исходниками
// 3. Компилируем TypeScript в JavaScript
npx tsc

// 4. Запускаем скомпилированный JS-файл
node dist/index.js

Если у вас в package.json стоит "type": "module", то компилируйте с "module": "ESNext" и запускайте как node dist/index.js. Если используете CommonJS — уберите "type": "module" из package.json.

Решение 2: Использование ts-node (для разработки)

ts-node — это пакет, который позволяет запускать .ts файлы напрямую, без предварительной компиляции.

// Устанавливаем ts-node
npm install --save-dev ts-node

// Теперь можно запускать напрямую:
npx ts-node index.ts

// Или добавить скрипт в package.json:
"scripts": {
    "start": "ts-node index.ts"
}
// Запуск: npm start

Важно: Если у вас "type": "module" в package.json, то при использовании ts-node может потребоваться дополнительная настройка. В этом случае лучше использовать tsx (альтернатива ts-node):

npm install --save-dev tsx
npx tsx index.ts

Решение 3: Использование nodemon + ts-node (для автоматической перезагрузки)

Для разработки удобно настроить автоматический перезапуск при изменениях:

npm install --save-dev nodemon ts-node

// В package.json добавить скрипт:
"scripts": {
    "dev": "nodemon --exec ts-node index.ts"
}
// Запуск: npm run dev

Проверка установки TypeScript

Убедитесь, что TypeScript установлен именно в ваш проект (локально), а не глобально. Глобальная установка может конфликтовать с разными версиями проектов.

// Проверяем локальную версию
npx tsc --version

// Если не установлен локально — устанавливаем:
npm install --save-dev typescript

Полный пример рабочего проекта

// package.json
{
  "name": "my-ts-project",
  "version": "1.0.0",
  "type": "module",
  "scripts": {
    "build": "tsc",
    "start": "node dist/index.js",
    "dev": "tsx index.ts"
  },
  "devDependencies": {
    "tsx": "^4.7.0",
    "typescript": "^5.3.0"
  }
}

// tsconfig.json
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "moduleResolution": "node",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true
  },
  "include": ["src/**/*"]
}

После этого просто поместите ваш index.ts в папку src/ и пользуйтесь командами npm run build или npm run dev.

<<>>

Альтернативный подход: Использование Node.js с флагом --experimental-loader

Если вы не хотите устанавливать дополнительные пакеты, можно воспользоваться экспериментальной возможностью Node.js — загрузчиком для TypeScript.

// Устанавливаем только TypeScript
npm install --save-dev typescript

// Создаём файл register.js в корне проекта:
import { register } from 'node:module';
import { pathToFileURL } from 'node:url';

register('typescript/lib/loader.mjs', pathToFileURL('./'));

// Теперь можно запускать:
node --experimental-loader ./register.js index.ts

Однако этот метод нестабилен и может сломаться при обновлении Node.js. Я рекомендую использовать его только для быстрых экспериментов.

Что делать, если ошибка остаётся?

  • Проверьте, нет ли в проекте файла .babelrc или babel.config.json, который может конфликтовать с TypeScript
  • Убедитесь, что в tsconfig.json нет опции "allowImportingTsExtensions": true без соответствующей настройки
  • Попробуйте удалить node_modules и package-lock.json, затем выполнить npm install заново
  • Если используете Windows, проверьте пути к файлам — иногда проблема в регистре символов

Самый надёжный путь для новичка — использовать tsx (решение 1) или настроить компиляцию через tsc (решение 2). Эти методы стабильно работают и поддерживаются сообществом.