Avatar ·

Ошибка "Cannot use JSX unless the '--jsx' flag is provided" в TypeScript и React

Всем привет! Я новичок в React и TypeScript, пытаюсь настроить свой первый проект. Установил create-react-app с шаблоном TypeScript, но при компиляции получаю ошибку: ``` Cannot use JSX unless the '--jsx' flag is provided. ``` Мой код в файле App.tsx выглядит так: ```tsx import React from 'react'; const App: React.FC = () => { return (

Hello, World!

); }; export default App; ``` Я создал проект через `npx create-react-app my-app --template typescript`. В папке есть tsconfig.json, но я в него не заглядывал. Когда запускаю `npm start`, всё работает, но если я пытаюсь скомпилировать проект вручную через `tsc`, то получаю эту ошибку. Также я заметил, что если я меняю расширение файла с .tsx на .ts, то ошибка исчезает, но тогда перестают работать JSX-теги (React ругается). Подскажите, что я делаю не так? Как правильно настроить TypeScript для работы с JSX? Нужно ли что-то менять в tsconfig.json? Почему create-react-app работает, а ручная компиляция — нет? Заранее спасибо за помощь! <<>>

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

Ошибка "Cannot use JSX unless the '--jsx' flag is provided" возникает, когда TypeScript-компилятор (tsc) не знает, как обрабатывать JSX-синтаксис в файлах с расширением .tsx. По умолчанию TypeScript не поддерживает JSX — эту возможность нужно явно включить.

В проектах, созданных через create-react-app, конфигурация уже настроена, поэтому npm start работает. Но при ручном запуске tsc вы используете настройки из tsconfig.json, которые могут быть неполными или отсутствовать.

Пошаговое решение

  1. Откройте файл tsconfig.json в корне вашего проекта. Если его нет — создайте.
  2. Добавьте (или измените) опцию "jsx" в секции compilerOptions:
{
  "compilerOptions": {
    "jsx": "react-jsx",    // для React 17+ (автоматический импорт)
    // или "jsx": "react"   // для React 16 и ниже (нужен явный import React)
  }
}

Объяснение значений jsx:

  • "react" — преобразует JSX в вызовы React.createElement. Требует явного импорта React в каждом файле: import React from 'react'.
  • "react-jsx" — использует новый JSX-трансформер (React 17+). Не требует явного импорта React.
  • "preserve" — оставляет JSX как есть (для дальнейшей обработки Babel).

Полный пример корректного tsconfig.json

{
  "compilerOptions": {
    "target": "ES6",
    "module": "ESNext",
    "jsx": "react-jsx",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true
  },
  "include": ["src"]
}

Почему create-react-app работает без этой настройки?

Create-react-app использует Babel для компиляции JSX, а TypeScript — только для проверки типов. Поэтому npm start работает даже с неполным tsconfig.json. Но если вы хотите компилировать проект через tsc (например, для сборки), нужно настроить "jsx" явно.

Дополнительные советы:

  • Убедитесь, что файлы с JSX имеют расширение .tsx, а не .ts.
  • Если используете React 16 или ниже, добавьте "jsx": "react" и не забывайте импортировать React.
  • Проверьте версию TypeScript: npx tsc --version. Для "react-jsx" нужен TypeScript 4.1+.

После изменения tsconfig.json запустите tsc снова — ошибка должна исчезнуть.

<<>>

Альтернативный подход: использование Babel вместо tsc

Если вы не хотите менять tsconfig.json или используете инструменты сборки (Webpack, Vite), можно делегировать обработку JSX Babel, а TypeScript оставить только для проверки типов.

Установите необходимые пакеты:

npm install --save-dev @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript

Создайте babel.config.json:

{
  "presets": [
    "@babel/preset-env",
    ["@babel/preset-react", { "runtime": "automatic" }],
    "@babel/preset-typescript"
  ]
}

В tsconfig.json установите "jsx": "preserve" — TypeScript не будет трогать JSX, оставляя его Babel:

{
  "compilerOptions": {
    "jsx": "preserve"
  }
}

Теперь компиляцию выполняет Babel, а TypeScript только проверяет типы (tsc --noEmit). Этот подход чаще используется в профессиональных проектах с Webpack или Vite.

Преимущества: больше гибкости, поддержка новых фич. Недостаток: дополнительная зависимость от Babel.