Airbnb's ESLint config with TypeScript support
npx @tessl/cli install tessl/npm-eslint-config-airbnb-typescript@18.0.0ESLint Config Airbnb TypeScript enhances Airbnb's popular ESLint configuration with comprehensive TypeScript support. It seamlessly bridges Airbnb's JavaScript style guide with TypeScript-specific requirements, providing both React-enabled and base configurations while maintaining full compatibility with existing Airbnb-based projects.
npm install eslint-config-airbnb-typescript @typescript-eslint/eslint-plugin@^7.0.0 @typescript-eslint/parser@^7.0.0 --save-devThis package provides ESLint configurations, not importable functions. Instead, it's used in ESLint configuration files:
For React + TypeScript projects:
{
"extends": ["airbnb", "airbnb-typescript"],
"parserOptions": {
"project": "./tsconfig.json"
}
}For base TypeScript projects (no React):
{
"extends": ["airbnb-base", "airbnb-typescript/base"],
"parserOptions": {
"project": "./tsconfig.json"
}
}Complete setup for React + TypeScript:
npm install eslint-config-airbnb-typescript \
@typescript-eslint/eslint-plugin@^7.0.0 \
@typescript-eslint/parser@^7.0.0 \
--save-dev.eslintrc.js:module.exports = {
extends: [
'airbnb',
'airbnb-typescript'
],
parserOptions: {
project: './tsconfig.json'
}
};npx eslint . --ext .js,.jsx,.ts,.tsxESLint Config Airbnb TypeScript is built around three key configuration modules:
index.js): Full Airbnb + React + TypeScript setupbase.js): Airbnb base + TypeScript (no React)lib/shared.js): Core TypeScript rule mappings and overridesThe package intelligently replaces 35+ JavaScript ESLint rules with their TypeScript equivalents, extends file resolution to handle TypeScript extensions, and provides specialized overrides for TypeScript files where the TypeScript compiler provides better checking than ESLint.
The default configuration for React projects with TypeScript support.
// Referenced via: "airbnb-typescript"
module.exports = {
extends: ['./lib/shared'],
settings: {
'import/resolver': {
node: {
extensions: ['.mjs', '.js', '.jsx', '.json', '.ts', '.tsx', '.d.ts']
}
}
},
rules: {
'react/jsx-filename-extension': ['error', { extensions: ['.jsx', '.tsx'] }]
}
};Usage:
{
"extends": ["airbnb", "airbnb-typescript"],
"parserOptions": {
"project": "./tsconfig.json"
}
}Base configuration for TypeScript projects without React.
// Referenced via: "airbnb-typescript/base"
module.exports = {
extends: ['./lib/shared.js']
};Usage:
{
"extends": ["airbnb-base", "airbnb-typescript/base"],
"parserOptions": {
"project": "./tsconfig.json"
}
}Core TypeScript configuration with rule overrides and parser setup.
// Referenced internally by other configurations
module.exports = {
plugins: ['@typescript-eslint'],
parser: '@typescript-eslint/parser',
settings: {
'import/parsers': {
'@typescript-eslint/parser': ['.ts', '.tsx', '.d.ts']
},
'import/resolver': {
node: {
extensions: ['.mjs', '.js', '.json', '.ts', '.d.ts']
}
},
'import/extensions': ['.js', '.mjs', '.jsx', '.ts', '.tsx', '.d.ts'],
'import/external-module-folders': ['node_modules', 'node_modules/@types']
},
rules: {
// 35+ rule overrides mapping JavaScript rules to TypeScript equivalents
},
overrides: [
{
files: ['*.ts', '*.tsx'],
rules: {
// Rules disabled for TypeScript files (handled by compiler)
}
}
]
};The shared configuration replaces JavaScript ESLint rules with TypeScript-specific equivalents:
// Core stylistic rule mappings
const styleRuleMappings = {
'brace-style': '@typescript-eslint/brace-style',
'comma-dangle': '@typescript-eslint/comma-dangle',
'comma-spacing': '@typescript-eslint/comma-spacing',
'func-call-spacing': '@typescript-eslint/func-call-spacing',
'indent': '@typescript-eslint/indent',
'keyword-spacing': '@typescript-eslint/keyword-spacing',
'lines-between-class-members': '@typescript-eslint/lines-between-class-members',
'object-curly-spacing': '@typescript-eslint/object-curly-spacing',
'quotes': '@typescript-eslint/quotes',
'semi': '@typescript-eslint/semi',
'space-before-blocks': '@typescript-eslint/space-before-blocks',
'space-before-function-paren': '@typescript-eslint/space-before-function-paren',
'space-infix-ops': '@typescript-eslint/space-infix-ops'
};// Best practices rule mappings
const bestPracticesRuleMappings = {
'default-param-last': '@typescript-eslint/default-param-last',
'dot-notation': '@typescript-eslint/dot-notation',
'no-empty-function': '@typescript-eslint/no-empty-function',
'no-implied-eval': '@typescript-eslint/no-implied-eval',
'no-loop-func': '@typescript-eslint/no-loop-func',
'no-magic-numbers': '@typescript-eslint/no-magic-numbers',
'no-redeclare': '@typescript-eslint/no-redeclare',
'no-throw-literal': '@typescript-eslint/no-throw-literal',
'no-unused-expressions': '@typescript-eslint/no-unused-expressions',
'no-useless-constructor': '@typescript-eslint/no-useless-constructor',
'require-await': '@typescript-eslint/require-await',
'no-return-await': '@typescript-eslint/return-await'
};// Variable and error rule mappings
const variableErrorRuleMappings = {
'camelcase': '@typescript-eslint/naming-convention',
'no-array-constructor': '@typescript-eslint/no-array-constructor',
'no-dupe-class-members': '@typescript-eslint/no-dupe-class-members',
'no-extra-parens': '@typescript-eslint/no-extra-parens',
'no-extra-semi': '@typescript-eslint/no-extra-semi',
'no-loss-of-precision': '@typescript-eslint/no-loss-of-precision',
'no-shadow': '@typescript-eslint/no-shadow',
'no-unused-vars': '@typescript-eslint/no-unused-vars',
'no-use-before-define': '@typescript-eslint/no-use-before-define'
};The package implements Airbnb's naming conventions for TypeScript:
// TypeScript naming convention rule
'@typescript-eslint/naming-convention': [
'error',
{
selector: 'variable',
format: ['camelCase', 'PascalCase', 'UPPER_CASE']
},
{
selector: 'function',
format: ['camelCase', 'PascalCase']
},
{
selector: 'typeLike',
format: ['PascalCase']
}
]Extended import resolution for TypeScript files:
// Import extensions configuration
'import/extensions': [
'error',
'ignorePackages',
{
js: 'never',
mjs: 'never',
jsx: 'never',
ts: 'never',
tsx: 'never'
}
]Rules disabled for TypeScript files as they're handled by the TypeScript compiler:
// Disabled rules for .ts and .tsx files
const disabledRulesForTypeScript = [
'constructor-super',
'getter-return',
'no-const-assign',
'no-dupe-args',
'no-dupe-class-members',
'no-dupe-keys',
'no-func-assign',
'no-import-assign',
'no-new-symbol',
'no-obj-calls',
'no-redeclare',
'no-setter-return',
'no-this-before-super',
'no-undef',
'no-unreachable',
'no-unsafe-negation',
'valid-typeof',
'import/named',
'import/no-named-as-default-member',
'import/no-unresolved'
];// package.json dependencies
{
"dependencies": {
"eslint-config-airbnb-base": "^15.0.0"
},
"peerDependencies": {
"@typescript-eslint/eslint-plugin": "^7.0.0",
"@typescript-eslint/parser": "^7.0.0",
"eslint": "^8.56.0"
}
}Required TypeScript parser configuration:
// Required parserOptions in ESLint config
{
"parserOptions": {
"project": string | string[], // Path(s) to tsconfig.json
"tsconfigRootDir": string // Optional: root directory for tsconfig
}
}For projects where ESLint needs to lint files not included in the main tsconfig.json:
{
"extends": "./tsconfig.json",
"include": [
"src/**/*.ts",
"src/**/*.js",
"test/**/*.ts"
]
}Then reference in ESLint config:
{
"parserOptions": {
"project": "./tsconfig.eslint.json"
}
}