Linter TypeScript avec ESLint
Configuration flat ESLint 10 pour TypeScript : setup avec typescript-eslint, lint typé avec projectService et Prettier sans conflit.
En juillet 2026, la manière actuelle de linter TypeScript consiste à utiliser ESLint 10 avec le package typescript-eslint en flat config (eslint.config.mjs) — et non l’ancienne configuration .eslintrc que la plupart des résultats de recherche affichent encore.
Si vous avez déjà collé une configuration issue d’un tutoriel de 2022 et constaté qu’ESLint l’ignorait complètement, voici pourquoi : elle a été écrite pour un système de configuration qui n’existe plus. Le remplacement est concis, même si la partie type-aware nécessite une option supplémentaire qu’on oublie facilement.
ESLint 10 a purement et simplement supprimé le système de configuration eslintrc, comme le projet l’avait annoncé dans ses plans de déploiement de la flat config. Ce seul changement rend caduc presque tous les tutoriels antérieurs à 2024, car ESLint ne lit plus du tout les fichiers .eslintrc ou .eslintignore. Ce guide vous fournit une flat config correcte et prête à copier-coller pour TypeScript, montre comment activer les règles type-aware, et intègre le linting à vos scripts, votre éditeur et votre CI.
Points clés à retenir
- La stack moderne, c’est ESLint 10 plus typescript-eslint v8 en flat config ;
.eslintrc/.eslintignoresont morts depuis ESLint 10. - Une configuration minimale passe
js.configs.recommendedettseslint.configs.recommendedàdefineConfig()importé depuiseslint/config, dans un fichier nomméeslint.config.js/.mjs. - Les règles type-aware comme
no-floating-promisesnécessitentparserOptions: { projectService: true }. UnparserOptionsvide ne les active pas. - Le linting typé demande à TypeScript de compiler votre projet avant le linting, il est donc plus lent ; exécutez-le en CI et appuyez-vous sur le cache de l’IDE dans l’éditeur.
- En flat config, le flag
--extest obsolète : le ciblage des fichiers se fait via le globfilesde chaque bloc, si bien que le script de lint se résume àeslint ..
ESLint et TypeScript font-ils le même travail ?
ESLint et TypeScript sont complémentaires, non concurrents. Une poignée de règles typescript-eslint s’appuient sur le vérificateur de types de TypeScript pour une analyse plus fine de votre code, mais les deux outils répondent à des questions différentes : le compilateur TypeScript vérifie la cohérence des types, tandis qu’ESLint fait respecter le style et détecte les bugs probables (variables inutilisées, promesses non gérées, patterns dangereux) dans l’ensemble de votre base de code. On utilise les deux.
Si vous migrez depuis TSLint, sachez qu’il est mort depuis des années. Ses mainteneurs ont annoncé en 2019 qu’ils allaient le déprécier au profit de typescript-eslint, et l’écosystème ESLint est devenu le standard pour linter TypeScript. Il n’y a aucune raison de se tourner vers TSLint dans un nouveau projet.
Un prérequis avant d’installer : ESLint 10 a abandonné les anciennes versions de Node. Il fonctionne désormais sur Node.js v20.19.0 et supérieur, v22.13.0 et supérieur, ou v24 et supérieur ; les versions v21.x et v23.x ne sont plus prises en charge.
Comment configurer ESLint pour TypeScript ?
Discover how at OpenReplay.com.
Installez les quatre packages réellement nécessaires :
npm i -D eslint @eslint/js typescript typescript-eslint
Le helper typescript-eslint regroupe le parser et le plugin, ce qui vous évite de câbler manuellement @typescript-eslint/parser et @typescript-eslint/eslint-plugin. Il prend en charge la version majeure actuelle : la plage ESLint documentée par typescript-eslint couvre ^8.57.0 || ^9.0.0 || ^10.0.0, donc typescript-eslint@latest (v8.x) fonctionne sans accroc sur ESLint 10.
Créez eslint.config.mjs (flat config, et non .eslintrc) :
// eslint.config.mjs
import js from '@eslint/js';
import { defineConfig } from 'eslint/config';
import tseslint from 'typescript-eslint';
export default defineConfig(
js.configs.recommended,
tseslint.configs.recommended,
);
Voilà une base fonctionnelle : les règles recommandées du cœur d’ESLint plus l’ensemble recommandé de typescript-eslint, qui définit pour vous le parser et le plugin typescript-eslint. defineConfig() provient du cœur d’ESLint et c’est le helper à privilégier désormais, car typescript-eslint a déprécié son propre tseslint.config() en sa faveur. L’ancien helper fonctionne toujours, une configuration existante n’est donc pas cassée, mais les nouvelles installations devraient utiliser defineConfig(). Continuez à importer tseslint dans les deux cas, puisque vous en avez toujours besoin pour tseslint.configs.* et les helpers de globs.
Passer en mode plus strict, puis ajuster les règles individuelles
recommended n’est que le point de départ ; deux presets optionnels relèvent le niveau d’exigence. tseslint.configs.strict ajoute des règles de correction plus tranchées, et tseslint.configs.stylistic ajoute des règles de cohérence qui ne nécessitent pas d’information de type. Ajoutez-les aux côtés de recommended dans le tableau de configuration.
Surchargez n’importe quelle règle dans un bloc rules. Les niveaux de sévérité sont au nombre de trois : off (ou 0) désactive complètement la règle, warn (ou 1) signale le problème sans affecter le code de sortie, et error (ou 2) le signale et fait sortir ESLint avec le code 1. Utilisez warn pour ce que vous voulez rendre visible sans bloquer ; utilisez error pour tout ce qui ne doit pas atteindre le dépôt, puisque cela produit un code de sortie non nul et fait échouer la CI.
rules: {
'@typescript-eslint/no-explicit-any': 'warn',
'@typescript-eslint/no-unused-vars': 'error',
}
Préférez les sévérités sous forme de chaînes ('warn'/'error') à la forme numérique dans les configurations modernes. Elles se lisent plus clairement, et le style purement numérique est une signature des tutoriels .eslintrc datés.
Linting type-aware : les règles qui ont besoin des informations de type
Certaines des règles les plus utiles, dont no-floating-promises et no-misused-promises, nécessitent des informations de type, et vous les activez en ajoutant parserOptions: { projectService: true }. C’est la méthode recommandée pour activer le linting typé depuis typescript-eslint v8, en remplacement de l’ancienne option project, car elle demande moins de configuration et s’exécute plus vite. Basculez également vos presets vers leurs variantes type-checked (recommendedTypeChecked, strictTypeChecked, stylisticTypeChecked). Un parserOptions: {} vide n’active pas le linting type-aware, une erreur fréquente dans les configurations copiées.
{
files: ['**/*.ts', '**/*.tsx'],
extends: [tseslint.configs.recommendedTypeChecked],
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
}
Le linting typé a un coût réel. L’activer signifie que TypeScript doit compiler votre projet avant qu’ESLint puisse le linter, soit une seconde ou deux sur une petite base de code et sensiblement plus sur une grande. Les recommandations de typescript-eslint s’appuient sur une asymétrie : les plugins d’éditeur mettent en cache les informations de type et échappent largement à cette pénalité ; exécutez donc le lint typé complet en CI et en pre-commit, et laissez l’éditeur vous couvrir au quotidien. projectService supprime également l’ancien contournement consistant à maintenir un tsconfig.eslint.json séparé, puisqu’il utilise le même projet que l’éditeur.
Séparez le JS du TS, et définissez vos ignores
Les règles type-checked n’ont de sens que sur les fichiers que TypeScript comprend : limitez-les donc à **/*.ts/**/*.tsx et désactivez-les pour le JavaScript pur. typescript-eslint fournit un preset précisément pour cela. Sa propre documentation applique tseslint.configs.disableTypeChecked à un bloc **/*.js pour retirer la configuration spécifique à TypeScript. En flat config, les ignores ne sont qu’un bloc de configuration ne contenant qu’une clé ignores, ce qui remplace .eslintignore.
// eslint.config.mjs
import js from '@eslint/js';
import { defineConfig } from 'eslint/config';
import tseslint from 'typescript-eslint';
import prettier from 'eslint-config-prettier';
export default defineConfig(
{ ignores: ['dist/', 'node_modules/', 'coverage/', '**/*.d.ts'] },
js.configs.recommended,
{
files: ['**/*.ts', '**/*.tsx'],
extends: [tseslint.configs.recommendedTypeChecked],
languageOptions: {
parserOptions: { projectService: true, tsconfigRootDir: import.meta.dirname },
},
rules: { '@typescript-eslint/no-explicit-any': 'warn' },
},
{ files: ['**/*.js', '**/*.mjs'], extends: [tseslint.configs.disableTypeChecked] },
prettier, // doit être en dernier
);
Laissez Prettier formater, puis mettez en place le workflow
Gardez le formatage hors d’ESLint. Ajoutez eslint-config-prettier en dernier pour désactiver les règles stylistiques d’ESLint qui entreraient en conflit avec Prettier, et figez-le en ^10.1.8 ou ultérieur. Cette version compte : en juillet 2025, une attaque de phishing sur les identifiants npm d’un mainteneur a conduit à quatre releases altérées, référencées sous CVE-2025-54313. Les versions 8.10.1, 9.1.1, 10.1.6 et 10.1.7 embarquaient un script postinstall qui exécutait une charge utile DLL sur les machines Windows ; les versions corrigées sont 8.10.2, 9.1.2 et 10.1.8. Seules ces quatre versions étaient affectées et la charge utile ne s’exécutait que sous Windows : les builds antérieurs sains, comme 10.1.5, n’ont jamais été compromis. Exécuter Prettier comme une règle ESLint via eslint-plugin-prettier est possible mais optionnel ; beaucoup d’équipes s’en passent car cela rend le linting plus lent et plus bruyant.
Ajoutez un script de lint. Aucun flag --ext n’est nécessaire, puisque le ciblage des fichiers se fait via le glob files de chaque bloc de configuration :
{
"scripts": {
"lint": "eslint .",
"lint:fix": "eslint . --fix"
}
}
À partir de là, exécutez eslint --fix sur les fichiers stagés avec Husky et lint-staged avant chaque commit, activez la correction à l’enregistrement dans VS Code via "source.fixAll.eslint": "explicit" dans codeActionsOnSave, et lancez eslint . comme étape de CI afin qu’une règle en échec bloque la fusion.
Un dernier point à traiter : ESLint 9 a atteint sa fin de vie le 06/08/2026 et ne reçoit plus aucune mise à jour. Si vous êtes encore sur ESLint 9, la configuration ci-dessus fonctionne telle quelle sur ESLint 10 : mettez à jour le runtime et passez à la suite. Partez de la configuration minimale de deux lignes, ajoutez recommendedTypeChecked avec projectService quand vous souhaitez les règles de sécurité sur les promesses, et placez eslint-config-prettier en dernier.
FAQ
Dois-je activer le linting type-aware, et quel en est le coût ?
Activez-le si vous voulez les règles de correction à plus forte valeur ajoutée comme no-floating-promises et no-misused-promises, qui ne peuvent pas fonctionner sans informations de type. Le coût, c'est qu'ESLint demande à TypeScript de compiler votre projet avant le linting, ce qui est négligeable sur les petits projets mais perceptible sur les grands. La plupart des équipes exécutent le lint typé complet en CI et en pre-commit et s'appuient sur le cache de l'IDE dans l'éditeur, où la pénalité est évitée.
Quelle est la différence entre projectService et project pour le linting typé ?
Les deux activent le linting typé, mais projectService est ce que typescript-eslint recommande depuis la v8 pour une configuration plus simple et un linting plus rapide, car il réutilise le même tsconfig.json que votre éditeur utilise déjà. L'ancienne option project vous oblige à pointer vers un ou plusieurs fichiers TSConfig par leur chemin et a souvent contraint les équipes à maintenir un tsconfig.eslint.json séparé. Utilisez projectService: true sauf si vous avez une raison précise de ne pas le faire.
Le flag --ext fonctionne-t-il encore dans la flat config d'ESLint ?
Non, --ext n'est plus nécessaire en flat config. Le ciblage des fichiers se fait à l'intérieur du glob files de chaque bloc de configuration, par exemple files: ['**/*.ts', '**/*.tsx'], donc ESLint sait déjà quels fichiers linter. Votre script de lint se réduit à eslint . sans flag d'extension. Les scripts qui passent encore --ext sont copiés de tutoriels antérieurs à la flat config, écrits pour le système eslintrc supprimé.
Dois-je utiliser eslint-config-prettier ou eslint-plugin-prettier ?
Utilisez eslint-config-prettier pour la plupart des projets. Il désactive les règles stylistiques d'ESLint qui entrent en conflit avec Prettier et n'ajoute aucune surcharge à l'exécution ; placez-le en dernier dans votre tableau de configuration. L'approche eslint-plugin-prettier exécute Prettier comme une véritable règle de lint, ce qui est optionnel et plus lent, et fait remonter chaque différence de formatage comme une erreur de lint. Figez eslint-config-prettier en 10.1.8 ou ultérieur pour rester à l'écart de l'incident de chaîne d'approvisionnement de juillet 2025.
Gain Debugging Superpowers
Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers.
Star on GitHub12k