Вступление: "Ваш файл .ts не открывается? Вы не одиноки"
Представьте: вы пишете крутой код на TypeScript, сохраняете файл с расширением .ts, запускаете команду node myfile.ts... и получаете в ответ нечто вроде: "Unknown file extension ".ts". Знакомо? Если вы заглядывали на Stack Overflow, то знаете, что этот вопрос собрал тысячи просмотров и сотни комментариев. Проблема старая, но до сих пор актуальная.
В этой статье мы не просто скопируем ответ с форума. Мы разберём почему это происходит, как это исправить, и что делать, чтобы больше никогда не сталкиваться с этой ошибкой. Вы узнаете, как правильно настроить TypeScript проект, использовать ts-node и конфигурацию tsconfig.json. Поехали!
Почему возникает ошибка "Unknown file extension ".ts"?
Давайте сразу к сути. Node.js по умолчанию не понимает файлы .ts. Он знает только .js, .json, .mjs и .cjs. Когда вы пишете node myfile.ts, Node.js честно пытается выполнить TypeScript код как обычный JavaScript, но натыкается на синтаксис, который ему незнаком (например, типы, интерфейсы, дженерики).
В результате — ошибка. Но есть и другая ситуация: вы используете ts-node или tsx, но всё равно видите то же сообщение. Почему? Потому что в современных версиях Node.js (начиная с 16-й) добавили строгую проверку расширений в package.json, особенно когда стоит "type": "module".
Основные причины:
- Прямой запуск
node file.ts— Node.js не умеет компилировать TypeScript на лету. - Отсутствие
ts-nodeилиtsx— нет инструмента для трансляции. - Неправильная конфигурация
tsconfig.json— например, не указан модуль или target. - Проблемы с
package.json— если стоит"type": "module", тоts-nodeможет требовать явного указания расширения.
Решение 1: Используем ts-node (классический способ)
Самый простой способ запускать TypeScript без предварительной компиляции — использовать ts-node. Это пакет, который компилирует .ts файлы в память и передаёт результат Node.js.
Установка и запуск
npm install -g ts-node
ts-node myfile.ts
Если вы используете локальный проект, лучше установить как dev-зависимость:
npm install --save-dev ts-node
npx ts-node myfile.ts
Пример простого файла hello.ts:
const greet = (name: string): string => {
return `Привет, ${name}!`;
};
console.log(greet("Мир"));
Запускаем: npx ts-node hello.ts — и видим в консоли "Привет, Мир!". Работает!
Но есть нюанс: "type": "module"
Если в вашем package.json указано "type": "module", то ts-node может отказаться работать. В этом случае нужно либо временно убрать эту строку, либо использовать флаг --esm:
npx ts-node --esm myfile.ts
Решение 2: Используем tsx (современный инструмент)
tsx — это более быстрая альтернатива ts-node, основанная на esbuild. Она работает с ESM из коробки и не требует дополнительных флагов.
Установка:
npm install --save-dev tsx
Запуск:
npx tsx myfile.ts
Пример с использованием современных возможностей TypeScript:
// types.ts
export interface User {
id: number;
name: string;
email: string;
}
const user: User = {
id: 1,
name: "Алексей",
email: "alex@example.com"
};
console.log(user);
Запускаем npx tsx types.ts — всё работает. Никаких ошибок с расширением.
Решение 3: Компиляция в JavaScript (традиционный подход)
Если вы не хотите использовать дополнительные инструменты, можно просто скомпилировать TypeScript в JavaScript с помощью tsc (TypeScript Compiler) и затем запустить обычный .js файл.
Шаги:
- Установите TypeScript глобально или локально:
npm install -g typescriptилиnpm install --save-dev typescript. - Создайте
tsconfig.json(можно черезtsc --init). - Запустите компиляцию:
tsc. - Запустите полученный
.jsфайл:node myfile.js.
Пример конфигурации tsconfig.json для простого проекта:
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
Теперь все файлы из папки src будут компилироваться в dist. Запускаем node dist/myfile.js — и никаких проблем с расширением .ts больше нет.
Решение 4: Настройка Node.js для прямого запуска .ts (экспериментально)
Начиная с Node.js 22, появилась экспериментальная поддержка TypeScript через флаг --experimental-strip-types. Это удаляет типы из кода и запускает его как JavaScript. Пока что это нестабильно, но попробовать можно:
node --experimental-strip-types myfile.ts
Однако этот способ не поддерживает сложные конструкции вроде декораторов или enum. Используйте на свой страх и риск.
Таблица сравнения способов
| Способ | Скорость | Простота | Поддержка ESM | Рекомендация |
|---|