Типичные конфигурации для TypeScript-проекта

В TypeScript-проектах ESLint выступает не только как инструмент проверки качества кода, но и как механизм контроля типовой корректности при использовании @typescript-eslint. Типичная конфигурация строится вокруг связки базового ESLint, TypeScript-парсера и набора рекомендуемых правил.

Основной пакет для работы с TypeScript:

  • typescript
  • eslint
  • @typescript-eslint/parser
  • @typescript-eslint/eslint-plugin

Структура конфигурации чаще всего начинается с определения парсера:

module.exports = {
  parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaVersion: 2022,
    sourceType: 'module',
    project: './tsconfig.json'
  }
};

Ключевой момент — параметр project. Он включает type-aware linting, позволяя ESLint анализировать типы, а не только синтаксис.

Подключение рекомендованных наборов правил

Типичный базовый набор включает две группы правил: ESLint core и TypeScript-specific.

module.exports = {
  extends: [
    'eslint:recommended',
    'plugin:@typescript-eslint/recommended'
  ]
};

Более строгий режим:

extends: [
  'eslint:recommended',
  'plugin:@typescript-eslint/recommended-type-checked',
  'plugin:@typescript-eslint/stylistic-type-checked'
]

Использование type-checked конфигураций увеличивает время анализа, но даёт более точные проверки, включая:

  • контроль несовместимости типов
  • выявление лишних проверок any
  • проверку возвратов функций
  • анализ Promise-цепочек

Базовая структура проекта ESLint в TypeScript

Стандартная организация конфигурации:

project/
 ├─ src/
 ├─ tsconfig.json
 ├─ eslint.config.js (или .eslintrc.js)
 ├─ package.json

В зависимости от версии ESLint используется либо классическая конфигурация (.eslintrc), либо flat config (eslint.config.js).

Конфигурация rules для TypeScript

Настройка правил требует баланса между строгостью и практичностью. Типовой набор:

rules: {
  '@typescript-eslint/no-unused-vars': 'error',
  '@typescript-eslint/no-explicit-any': 'warn',
  '@typescript-eslint/explicit-function-return-type': 'off',
  '@typescript-eslint/no-non-null-assertion': 'warn'
}

Каждое правило регулирует отдельный аспект:

  • no-unused-vars — контроль неиспользуемых переменных
  • no-explicit-any — ограничение на использование any
  • explicit-function-return-type — контроль явных типов возвращаемых значений
  • no-non-null-assertion — ограничение оператора !

Подключение parserOptions.project и типовая проверка

Type-aware linting требует подключения TypeScript конфигурации. Это влияет на производительность и возможности анализа.

parserOptions: {
  project: ['./tsconfig.json'],
  tsconfigRootDir: __dirname
}

При использовании монорепозиториев:

parserOptions: {
  project: ['./packages/*/tsconfig.json']
}

Важно учитывать, что ESLint начинает выполнять TypeScript program building, что увеличивает нагрузку на процесс линтинга.

Использование plugin:@typescript-eslint

Плагин предоставляет набор расширенных правил, недоступных в базовом ESLint:

  • анализ типов
  • контроль небезопасных конструкций
  • улучшенная диагностика async-кода

Пример подключения:

plugins: ['@typescript-eslint']

Расширенные правила:

rules: {
  '@typescript-eslint/restrict-template-expressions': 'error',
  '@typescript-eslint/consistent-type-imports': 'error',
  '@typescript-eslint/no-misused-promises': 'error'
}

Конфигурация import-правил в TypeScript

Для контроля импортов используется eslint-plugin-import, который требует дополнительной настройки резолвинга TypeScript:

settings: {
  'import/resolver': {
    typescript: {}
  }
}

Типичные правила:

rules: {
  'import/no-unresolved': 'off',
  'import/order': ['error', {
    alphabetize: { order: 'asc' },
    'newlines-between': 'always'
  }]
}

TypeScript сам управляет резолвингом, поэтому некоторые правила ESLint необходимо отключать.

Flat config (ESLint 9+) в TypeScript проектах

Современный формат конфигурации строится вокруг массива объектов:

import tseslint from '@typescript-eslint/eslint-plugin';
import tsparser from '@typescript-eslint/parser';

export default [
  {
    files: ['**/*.ts'],
    languageOptions: {
      parser: tsparser,
      parserOptions: {
        project: './tsconfig.json'
      }
    },
    plugins: {
      '@typescript-eslint': tseslint
    },
    rules: {
      '@typescript-eslint/no-explicit-any': 'warn'
    }
  }
];

Особенность flat config — отсутствие наследования extends в классическом виде, конфигурация становится более явной и композиционной.

Игнорирование файлов и производительность

Для оптимизации анализа используются .eslintignore или ignores в flat config.

node_modules
dist
build
coverage

В flat config:

{
  ignores: ['dist/**', 'node_modules/**']
}

Ускорение достигается за счёт исключения:

  • сгенерированных файлов
  • бандлов
  • деклараций .d.ts (в некоторых случаях)

Настройка для React + TypeScript

В проектах с React добавляется eslint-plugin-react и eslint-plugin-react-hooks.

extends: [
  'plugin:react/recommended',
  'plugin:react-hooks/recommended',
  'plugin:@typescript-eslint/recommended'
]

Ключевые настройки:

settings: {
  react: {
    version: 'detect'
  }
}

Правила:

rules: {
  'react/react-in-jsx-scope': 'off',
  'react-hooks/rules-of-hooks': 'error'
}

TypeScript требует отключения некоторых устаревших React-правил.

Конфигурация для Node.js TypeScript проектов

Для backend-проектов добавляется eslint-plugin-n:

extends: [
  'plugin:@typescript-eslint/recommended',
  'plugin:n/recommended'
]

Правила:

rules: {
  'n/no-missing-import': 'off',
  'n/no-unsupported-features/es-syntax': 'off'
}

Причина отключения — использование TypeScript, который транспилирует современный синтаксис.

Monorepo и масштабируемые конфигурации

В монорепозиториях ESLint конфигурация становится многоуровневой:

packages/
  app/
  shared/
  ui/
eslint.config.js

Подходы:

  • единый root config
  • пакетные overrides
  • отдельные tsconfig для каждого пакета

Пример overrides:

overrides: [
  {
    files: ['packages/ui/**/*.ts'],
    rules: {
      '@typescript-eslint/no-explicit-any': 'off'
    }
  }
]

Интеграция с Prettier

ESLint и Prettier часто используются совместно, при этом конфликты правил устраняются через eslint-config-prettier.

extends: [
  'plugin:@typescript-eslint/recommended',
  'prettier'
]

ESLint отвечает за качество кода, Prettier — за форматирование.

Отключаемые правила форматирования:

  • отступы
  • кавычки
  • длина строк
  • пробелы

Типичные ошибки конфигурации

В TypeScript-проектах часто встречаются следующие проблемы:

  • отсутствие parserOptions.project, из-за чего type-aware правила не работают
  • конфликт версий TypeScript и @typescript-eslint
  • чрезмерное использование any без контроля
  • включение тяжёлых правил в больших кодовых базах
  • дублирование правил ESLint и TypeScript compiler options

Практика разделения конфигураций

Для сложных проектов применяется разделение логики:

  • base config (общие правила)
  • node config
  • react config
  • test config

Пример:

module.exports = {
  extends: [
    './eslint.base.js',
    './eslint.node.js'
  ]
};

Тестовые окружения (Jest/Vitest):

overrides: [
  {
    files: ['**/*.test.ts'],
    env: {
      jest: true
    },
    rules: {
      '@typescript-eslint/no-explicit-any': 'off'
    }
  }
]

Такой подход позволяет управлять строгими правилами в зависимости от контекста исполнения кода.