npm package: @heinzelman-labs/eslint-config-typescript
Description: Heinzelman TypeScript ESLint configuration based on @typescript-eslint/eslint-plugin
Author: Micha Meyer
Latest version: 2.1.0

# @heinzelman-labs/eslint-config-typescript

[![npm version](https://img.shields.io/npm/v/@heinzelman-labs/eslint-config-typescript?style=flat-square)](https://www.npmjs.com/package/@heinzelman-labs/eslint-config-typescript)
[![total downloads](https://img.shields.io/npm/dt/@heinzelman-labs/eslint-config-typescript?style=flat-square)](https://www.npmjs.com/package/@heinzelman-labs/eslint-config-typescript)
[![monthly downloads](https://img.shields.io/npm/dm/@heinzelman-labs/eslint-config-typescript?style=flat-square)](https://www.npmjs.com/package/@heinzelman-labs/eslint-config-typescript)
[![license](https://img.shields.io/badge/license-MIT-brightgreen?style=flat-square)](https://www.npmjs.com/package/@heinzelman-labs/eslint-config-typescript)

A personal ESLint shareable config for TypeScript projects based on the [recommended rules](https://github.com/typescript-eslint/typescript-eslint/blob/v4.24.0/packages/eslint-plugin/src/configs/recommended.ts) defined by [`@typescript-eslint/eslint-plugin`](https://github.com/typescript-eslint/typescript-eslint/tree/v4.24.0/packages/eslint-plugin) `5.59.11`.

TypeScript rules only apply to `.ts` and `.tsx` files so that this config also works for mixed JS/TS code bases.

## References

At a minimum (using the `fast` config), this config extends the [`eslint-recommended`](https://github.com/typescript-eslint/typescript-eslint/blob/v4.24.0/packages/eslint-plugin/src/configs/eslint-recommended.ts) and [`recommended`](https://github.com/typescript-eslint/typescript-eslint/blob/v4.24.0/packages/eslint-plugin/src/configs/recommended.ts) configs provided by `@typescript-eslint/eslint-plugin` `5.59.11`.

While `eslint-recommended` disables such Eslint rules that are already handled natively by TypeScript, `recommended` contains the generally recommended rule configs for TypeScript projects.

The default config provided by this package additionally extends [`recommended-requiring-type-checking`](https://github.com/typescript-eslint/typescript-eslint/blob/v4.24.0/packages/eslint-plugin/src/configs/recommended-requiring-type-checking.ts).

Source code of the package can be found on ...
- [Gitlab](https://gitlab.com/fluffy-heinzelman/eslint-configs/-/tree/master/packages/eslint-config-typescript)
- [GitHub (Mirror)](https://github.com/fluffy-heinzelman/eslint-configs/tree/master/packages/eslint-config-typescript)

## Installation

### yarn 

```bash 
yarn add -D @heinzelman-labs/eslint-config-typescript
```

### npm 

```bash 
npm i -D @heinzelman-labs/eslint-config-typescript
```

## Usage

### Basic `.eslintrc.js` *with* type-checking

The default config provided by `@heinzelman-labs/eslint-config-typescript` does not only extend from `@typescript-eslint/recommended` but also from `@typescript-eslint/recommended-requiring-type-checking`. These highly valuable rules require type information, thus you will need to add a `tsconfig.json` to your project directory.

```javascript 
module.exports = {
    extends: [
        // Typically either using base or React Eslint config ...
        '@heinzelman-labs/eslint-config-react',
        // ... in tandem with the TypeScript Eslint config.
        '@heinzelman-labs/eslint-config-typescript'
    ],
    rules: {
        // Customize base / React rules ...
    },
    overrides: [
        {
            files: ['*.ts', '*.mts', '*.cts', '*.tsx'],
            rules: {
                // Customize TypeScript rules ...
            }
        },
        {
            files: ['*.tsx'],
            rules: {
                // Customize rules exclusively for TypeScript components ...
            }
        }
    ],
    env: {
        // Environments as needed ...
    }
};
```

### Basic `.eslintrc.js` *without* type-checking

In order to only use fast feedback rules which operate purely based on syntax, extend from `@heinzelman-labs/eslint-config-typescript/fast`. This may come in handy when dealing with really large codebases or you feel that ESLint is slow when it's run by your IDE.

```diff 
  module.exports = {
    // ...
    extends: [
-       '@heinzelman-labs/eslint-config-typescript'
+       '@heinzelman-labs/eslint-config-typescript/fast'
    ]
    // ...
  };
```

### Mono-Repo `.eslintrc.js`

For mono-repos using either [`@heinzelman-labs/eslint-config-base`](https://gitlab.com/fluffy-heinzelman/eslint-configs/-/tree/master/packages/eslint-config-base) or [`@heinzelman-labs/eslint-config-react`](https://gitlab.com/fluffy-heinzelman/eslint-configs/-/tree/master/packages/eslint-config-react) don't forget to add your package directories.

```javascript 
const { resolve } = require('path');

module.exports = {
    // ...
    rules: {
        'import/no-extraneous-dependencies': ['error', { 
            packageDir: [
                __dirname,
                resolve(__dirname, 'packages/foo'),
                resolve(__dirname, 'packages/bar')
            ]
        }]
    }
    // ...
};
```

### CLI

I would recommend to not use glob patterns or filenames, but to use directories to specify target files where possible. Then use the `--ext` option to define relevant file extensions. This way ESLint will not complain if you end up not having a certain file type among your sources anymore, e.g. `.js`. You may also use `.eslintignore` to exclude files from the result set as needed.

```bash
eslint ./src --ext .js,.ts,.tsx
```

## Changes compared to `eslint-config-base`, `eslint-config-react`, `@typescript-eslint/eslint-plugin`

Although this config does neither actively extend [`@heinzelman-labs/eslint-config-base`](https://gitlab.com/fluffy-heinzelman/eslint-configs/-/tree/master/packages/eslint-config-base) nor [`@heinzelman-labs/eslint-config-react`](https://gitlab.com/fluffy-heinzelman/eslint-configs/-/tree/master/packages/eslint-config-react), it does adjust some of their rules because I personally often use one of them in tandem with `@heinzelman-labs/eslint-config-typescript` and some of their rules just don't make sense in a TypeScript context. 

### Difference from `@heinzelman-labs/eslint-config-base`

```diff
  // Can be turned off for TypeScript projects because TypeScript
  // does its own lookups.
- 'import/no-unresolved': ['error', { 
-     commonjs: true, 
-     caseSensitive: true 
- }],
+ 'import/no-unresolved': 'off',

  // Rule must be disabled as it can report incorrect errors. 
  // `@typescript-eslint/no-use-before-define` is used instead.
- 'no-use-before-define': ['error', { 
-     functions: false, 
-     classes: true, 
-     variables: false 
- }],
+ 'no-use-before-define': 'off'
```

Note: A number of other rules get disabled or modified by  [`eslint-recommended`](https://github.com/typescript-eslint/typescript-eslint/blob/v4.24.0/packages/eslint-plugin/src/configs/eslint-recommended.ts), [`recommended`](https://github.com/typescript-eslint/typescript-eslint/blob/v4.24.0/packages/eslint-plugin/src/configs/recommended.ts) and [`recommended-requiring-type-checking`](https://github.com/typescript-eslint/typescript-eslint/blob/v4.24.0/packages/eslint-plugin/src/configs/recommended-requiring-type-checking.ts).

### Difference from `@heinzelman-labs/eslint-config-react`

```diff
  // Typically not using PropTypes in TypeScript projects, so only 
  // error on components that have a propTypes block declared.
  'react/prop-types': ['error', {
      ignore: [],
      customValidators: [],
-     skipUndeclared: false,
+     skipUndeclared: true
  }]
```

### Difference from `@typescript-eslint/eslint-plugin`

#### `eslint-recommended`

No changes.

#### `recommended`

```diff
- '@typescript-eslint/no-empty-function': 'error',
+ '@typescript-eslint/no-empty-function': ['error', {
+     allow: [
+         'arrowFunctions',
+         'functions',
+         'methods'
+     ]
+ }],

- '@typescript-eslint/no-unused-vars': 'warn',
+ '@typescript-eslint/no-unused-vars': ['error', {
+     vars: 'all',
+     varsIgnorePattern: '^React$',
+     args: 'after-used',
+     ignoreRestSiblings: true
+ }]
```

#### `recommended-requiring-type-checking`

No changes.

#### Additional rule configs

```javascript
'@typescript-eslint/explicit-function-return-type': ['error', {
    allowExpressions: true
}],

'@typescript-eslint/no-use-before-define': ['error', {
    functions: false,
    classes: true,
    variables: false,
    enums: true,
    typedefs: false,
    ignoreTypeReferences: true
}]
```

## License

[MIT License](LICENSE.md)