Airbnb ESLint configurations for mixed-type project with both TypeScript and JavaScript files.
The following is updated for
typescript-eslint@2.xwhere stylistic rules are removed from the recommended ruleset. See typescript-eslint#651 and PR typescript-eslint#729 for more details. Fortypescript-eslint@1.x, see here.
The goal is for the ESLint config to follow Airbnb Style Guide and typescript-eslint/recommended in order of precedence.
Note that neither ordering airbnb-base nor typescript-eslint/recommended ruleset first will acheive the desired configuration.
For example, if airbnb-base is ordered first, the camelcase rule of airbnb will be overrided by @typescript-eslint/camelcase rule. On the other hand, if typescript-eslint/recommended is ordered first, @typescript-eslint/camelcase will still be turned on, in addition to airbnb's camelcase rule.
// `airbnb` unused-vars rule: ['error', { ..., ignoreRestSiblings: true }] // `typescript-eslint/recommended` unused-vars rule: ['warn', { ..., ignoreRestSiblings: false }] // Following is allowed using `airbnb` but will result in warning: 'type' is defined but never used const { type, ...coords } = data;Lastly, there are some compatibility issues which would require certain airbnb rules to be disabled for TypeScript files. A good reference for such compatibility issues found in the react-app config and are described in the following issues.
- facebook/create-react-app#6906
- typescript-eslint/typescript-eslint#291
- typescript-eslint/typescript-eslint#477
ESLint 6.0 is required to if using extends in overrides configuration using glob patterns. It is also assumed that checkJs flag is not set to true in tsconfig.json.
The eslint-recommended ruleset is used after extending airbnb-base. Originally meant to be used after extending eslint:recommended ruleset, it disables rules for *.ts(x) files that are already checked by the Typescript compiler. It is also applicable here as airbnb-base ruleset is a superset of eslint:recommended.
The typescript-eslint/recommended and typescript-eslint/recommended-requiring-type-checking rulesets are used next. See here for more details about both rulesets.
typescript-eslint/recommended-requiring-type-checkingrequires a path to yourtsconfig.jsonfile in the "project" property of "parserOptions". If you do not do this, you will get a runtime error. As the rule applies to*.jsfiles, this assumesallowJsis set totrueintsconfig.json.
Next, import/typescript plugin is used to support linting of ES2015+ (ES6+) import/export syntax for TypeScript.
Specific rules overrides are then required to 'restore' airbnb rules. These rules are derived by inspecting ESLint rules in both typescript-eslint/recommended and typescript-eslint/recommended-requiring-type-checking, and comparing them to the airbnb ruleset.
In summary, the proposed config for TypeScript Airbnb style will
- Extends from
airbnb-base. - Extends from
plugin:@typescript-eslint/eslint-recommendedto turn off ESLint equivalent ESLint rules only for*.ts(x)files. - Extends from
typescript-eslint/recommendedandtypescript-eslint/recommended-requiring-type-checking.- For rules with ESLint equivalents, override rules if required to follow
airbnb.
- For rules with ESLint equivalents, override rules if required to follow
- [WIP]: Replace remaining
airbnbrules bytypescript-eslintequivalent if available. - For TypeScript files
- Disable
airbnbESLint rules wheretscdoes a better job or where it does not play well with TypeScript files, if they are not already turned off by previous rulesets.
- Disable
If path mapping is used by specifying "paths" property in tsconfig.json, eslint-import-resolver-typescript is required for eslint-plugin-import to resolve imports correctly.
"settings": { // Settings for eslint-plugin-import resolver "import/resolver": { // Settings for eslint-import-resolver-typescript to resolve TypeScript path mapping. "typescript": {}, }, },There are 2 parsers that can be used, babel-eslint and @typescript-eslint/parser. See here for the differences between them.
ts.eslintrc configuration uses @typescript-eslint/parser and babel.eslintrc configuration uses babel-eslint.
This project can be used to test rules parity using the two parsers.
# Run ESLint using `@typescript-eslint/parser` npm run lint # Run ESLint using `babel-eslint` npm run lint:babelTo detect cyclic dependencies (import/no-cycle) in files with TypeScript imports, plugin:import/typescript is required.
See here for the plugin settings.
"extends": [ // Following requires `@typescript-eslint/parser` "plugin:import/typescript", ],To detect cyclic dependencies (import/no-cycle) in files with TypeScript imports, you need to specify the extensions to be parsed as modules and inspected for exports
Note that using @typescript-eslint plugin will override the parser used (See source).
"settings": { // Specifiy file extensions to be parsed as modules and inspected for `export`s "import/extensions": [".js", ".ts"], }If the TypeScript project does not use path mapping (see above), eslint-import-resolver-typescript is not required. The following settings is required by import/no-unresolved to resolve TypeScript imports.
"settings": { // Settings for eslint-plugin-import resolver "import/resolver": { // Settings for eslint-import-resolver-node "node": { "extensions": [".js", ".ts"], }, }, }Alternatively, plugin:import/typescript can be used. This however requires @typescript-eslint/parser. This is equivalent to the next section on using both parser.
If using babel-eslint parser, a different parser (@typescript-eslint/parser) can be used by eslint-plugin-import for TypeScript files by specifying the following. (See here for the plugin settings.)
"extends": [ "plugin:import/typescript", ],There is an known issue with performance when referencing tsconfig.json in .eslintrc. See typescript-eslint/typescript-eslint/#389 for more details.
@typescript-eslint/eslint-plugin
@typescript-eslint/eslint-plugin Rules / Config