Search code examples
typescripteslintvscode-extensions

How do I configure ESLint flat config with TypeScript in VS Code (without FlatCompat)?


How do I:

  • transition to ESLint flat config
  • set up linting config for TypeScript in the new format
  • get the ESLint extension working again in VS Code

Solution

  • ESLint flat config is quite different from the previous format. To help understand the "flat config" the following pointers helped me:

    • Config is nothing more complicated than an array of objects. This is simpler than the previous format but might not be obvious at first.
    • Each object in the array can define whatever ESLint configuration it wants
    • Each object can target certain files by including or ignoring a set of files (useful because .eslintignore is no longer available)
    • Each file being linted will have all matching configurations applied - I believe in the order they appear in the array

    Setup for VS Code - at the time of writing you'll need:

    • ESLint plugin v3.0.5 or above (this currently requires "switch to pre-release version") in the plugin's installation page
    • Add "eslint.useFlatConfig": true to your settings.json (this was previously eslint.experimental.useFlatConfig)

    Install the following dependencies:

        yarn add --dev \
          eslint \
          @eslint/js \
          typescript-eslint \
          --
    

    Use the following eslint.config.js file to get you started (locate it alongside package.json). This provides defaults from https://typescript-eslint.io/getting-started/. This config additionally allows you to add ignored files, which is useful because .eslintignore is no longer available. NB the config is 'just Javascript' so you can make additional changes. This uses module.exports which avoids the need to add type: "module" to package.json:

        const eslint = require('@eslint/js');
        const tseslint = require('typescript-eslint');
    
        const ignores = [
          '**/*.js',
        ];
    
        module.exports = tseslint.config(
          {
            ...eslint.configs.recommended,
            ignores,
          },
          ...tseslint.configs.recommended.map((config) => ({
            ...config,
            ignores,
          })),
        );
    

    Pro:

    • It's actually quite clean
    • The config above is a lot smaller than the sticky nest of stuff I had accumulated under the old config

    Con:

    • I was previously using AirBnB config but decided I needed to dump that because it's not (yet) available in flat config format
    • Applying a different set of linting rules meant a raft of (mostly simple) changes across my codebase